package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.ciei.dpagm.common.converter.JsonConverter;
import com.ciei.dpagm.common.enums.*;
import com.ciei.dpagm.common.service.BaseService;
import com.ciei.dpagm.entity.*;
import com.ciei.dpagm.mapper.ProjectMapper;
import com.ciei.dpagm.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author pp
 * @date 2023/05/06
 */
@Service
public class ProjectService extends BaseService<ProjectMapper, Project> {

    @Value("${baseFilePath}")
    private String baseFilePath;

    @Autowired
    private ProjectMasterChipConfigService projectMasterChipConfigService;

    @Autowired
    private FilesService filesService;

    @Autowired
    private ProjectMasterChipClockParameterService projectMasterChipClockParameterService;

    @Autowired
    private ChipService chipService;

    @Autowired
    private ChipControlModeService chipControlModeService;

    @Autowired
    private ChipInterfaceService chipInterfaceService;

    @Autowired
    private ProjectSlaveChipConfigInterfaceService projectSlaveChipConfigInterfaceService;

    @Autowired
    private ProjectSlaveChipConfigInterfaceParameterService projectSlaveChipConfigInterfaceParameterService;

    @Autowired
    private ProjectSlaveChipConfigInterfacePinService projectSlaveChipConfigInterfacePinService;

    @Autowired
    private ChipPinService chipPinService;

    @Autowired
    private ProjectSlaveChipConfigService projectSlaveChipConfigService;

    @Autowired
    private FormLayoutService formLayoutService;

    @Autowired
    private FormPropertyService formPropertyService;

    @Autowired
    private ProjectSlaveChipConfigInterfacePinParameterService projectSlaveChipConfigInterfacePinParameterService;

    @Autowired
    private ChipControlModeInterfaceService chipControlModeInterfaceService;

    @Autowired
    private ChipControlModeInterfaceTypeService chipControlModeInterfaceTypeService;

    @Autowired
    private DriverLibraryService driverLibraryService;

    @Autowired
    private DriverLibraryDirectoryService driverLibraryDirectoryService;

    @Autowired
    private DriverLibraryConfigService driverLibraryConfigService;

    @Autowired
    private RuleSetService ruleSetService;

    @Autowired
    private RuleService ruleService;

    @Autowired
    private ConditionService conditionService;

    @Autowired
    private ChipClockParameterService chipClockParameterService;

    /**
     * 获取列表
     * @param webData
     * @return
     */
    public JSONObject getList(JSONObject webData){
        List<Project> projectList;
        String name = webData.getString("name");
        int projectSumNumber;
        if(StringUtils.isBlank(name)){
            projectList = findAll();
            projectSumNumber = projectList.size();
        }else{
            LambdaQueryWrapper<Project> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.like(Project::getName, name);
            projectList = list(lambdaQueryWrapper);
            projectSumNumber = count();
        }
        List<JSONObject> projectDataList = new ArrayList<>();
        for(Project project : projectList){
            JSONObject data = new JSONObject();
            data.fluentPut("projectId",project.getProjectId())
                    .fluentPut("name",project.getName() == null ? "" : project.getName())
                    .fluentPut("description",project.getDescription() == null ? "" : project.getDescription())
                    .fluentPut("updateTime",project.getUpdateTime() == null ? "" : project.getUpdateTime());
            projectDataList.add(data);
        }
        JSONObject data = new JSONObject();
        data.fluentPut("projectList",projectDataList)
                .fluentPut("projectSumNumber",projectSumNumber);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,data);
    }

    /**
     * 新增
     * @param webData
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject add(JSONObject webData, Users user){
        Project project = new Project();
        JsonConverter<Project> jsonConverter = new JsonConverter<>();
        project = jsonConverter.convert(webData, project);
        if(StringUtils.isBlank(project.getName())){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"项目名称不能为空");
        }
        LambdaQueryWrapper<Project> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Project::getName,project.getName());
        if(count(lambdaQueryWrapper) > 0){
            return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"项目名称重复，请重新输入");
        }
        project.setCreatorId(user.getUserId());
        project.setUpdateTime(new Date());
        project.setUpdateUserId(user.getUserId());
        save(project);
        JSONObject data = new JSONObject();
        data.fluentPut("projectId",project.getProjectId());
        return init(data);
    }

    /**
     * 更新
     * @param webData
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject update(JSONObject webData, Users user){
        Project project = new Project();
        JsonConverter<Project> jsonConverter = new JsonConverter<>();
        project = jsonConverter.convert(webData, project);
        if(project.getProjectId() == null){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"projectId不能为空");
        }
        if(StringUtils.isBlank(project.getName())){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"项目名称不能为空");
        }
        LambdaQueryWrapper<Project> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Project::getName,project.getName())
                .ne(Project::getProjectId,project.getProjectId());
        if(count(lambdaQueryWrapper) > 0){
            return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"项目名称重复，请重新输入");
        }
        project.setUpdateUserId(user.getUserId());
        project.setUpdateTime(new Date());
        updateById(project);
        JSONObject data = new JSONObject();
        data.fluentPut("projectId",project.getProjectId());
        return init(data);
    }

    /**
     * 初始化
     * @param webData
     * @return
     */
    public JSONObject init(JSONObject webData){
        Integer projectId = webData.getInteger("projectId");
        Project project = findById(projectId);
        if(project == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的项目，请检查传入的projectId是否有误");
        }
        JSONObject data = new JSONObject();
        data.fluentPut("projectId",project.getProjectId())
                .fluentPut("name",project.getName() == null ? "" : project.getName())
                .fluentPut("description",project.getDescription() == null ? "" : project.getDescription());
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,data);
    }

    /**
     * 删除
     * @param webData
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject delete(JSONObject webData){
        Integer projectId = webData.getInteger("projectId");
        if(projectId == null){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"projectId不能为空");
        }
        removeById(projectId);
        List<ProjectMasterChipConfig> projectMasterChipConfigList = projectMasterChipConfigService.findByProperty(ProjectMasterChipConfig::getProjectId, projectId);
        List<Integer> projectMasterChipConfigIdList = projectMasterChipConfigList.stream().map(ProjectMasterChipConfig::getProjectMasterChipConfigId).collect(Collectors.toList());
        if(!projectMasterChipConfigIdList.isEmpty()){
            projectMasterChipConfigService.removeByIds(projectMasterChipConfigIdList);
            projectMasterChipClockParameterService.removeByConfigIdList(projectMasterChipConfigIdList);
        }
        List<ProjectSlaveChipConfig> projectSlaveChipConfigList = projectSlaveChipConfigService.findByProperty(ProjectSlaveChipConfig::getProjectId, projectId);
        List<Integer> projectSlaveChipConfigIdList = projectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getProjectSlaveChipConfigId).collect(Collectors.toList());
        if(!projectSlaveChipConfigIdList.isEmpty()){
            projectSlaveChipConfigService.removeByIds(projectSlaveChipConfigIdList);
            projectSlaveChipConfigInterfaceService.removeByConfigIdList(projectSlaveChipConfigIdList);
            projectSlaveChipConfigInterfacePinService.removeByConfigIdList(projectSlaveChipConfigIdList);
            projectSlaveChipConfigInterfaceParameterService.removeByConfigIdList(projectSlaveChipConfigIdList);
            formPropertyService.deleteBatchByBusinessKeys(projectSlaveChipConfigIdList.stream().map(Object::toString).collect(Collectors.toList()), FormBusinessModuleEnum.SLAVE_CHIP_PARAMETER.getModuleId());
        }
        return JsonUtil.getSuccess("删除成功");
    }

    /**
     * 批量删除
     * @param webData
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject batchDelete(JSONObject webData){
        JSONArray projectIds = webData.getJSONArray("projectIds");
        if(projectIds == null || projectIds.isEmpty()){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"projectIds不能为空");
        }
        List<Integer> projectIdList = projectIds.toJavaList(Integer.class);
        removeByIds(projectIdList);
        return JsonUtil.getSuccess("批量删除成功");
    }
    /**
     * 初始化配置
     * @param webData
     * @return
     */
    public JSONObject initConfig(JSONObject webData){
        Integer projectId = webData.getInteger("projectId");
        if(projectId == null){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"projectId不能为空");
        }
        Project project = findById(projectId);
        if(project == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的项目，请检查传入的projectId是否有误");
        }

        JSONObject layoutContent = JSONObject.parseObject(project.getLayoutContent());
        if(layoutContent !=null && layoutContent.getJSONObject("content") != null){
            JSONObject content = layoutContent.getJSONObject("content");
            if(content.getJSONArray("nodes") != null){
                JSONArray nodes = content.getJSONArray("nodes");
                List<String> masterChipComponentIdList = new ArrayList<>();
                List<JSONObject> masterChipNodeDataList = new ArrayList<>();
                for(int i = 0; i < nodes.size();i++){
                    JSONObject nodeData = nodes.getJSONObject(i);
                    JSONObject data = nodeData.getJSONObject("data");
                    if(ChipTypeEnum.MASTER.getType().equals(data.getInteger("chipType"))){
                        masterChipComponentIdList.add(nodeData.getString("id"));
                        masterChipNodeDataList.add(nodeData);
                    }
                }
                List<ProjectMasterChipConfig> projectMasterChipConfigList = projectMasterChipConfigService.getList(masterChipComponentIdList);
                List<Integer> projectMasterChipConfigIdList = projectMasterChipConfigList.stream().map(ProjectMasterChipConfig::getProjectMasterChipConfigId).collect(Collectors.toList());
                List<ProjectMasterChipClockParameter> projectMasterChipClockParameterList = projectMasterChipClockParameterService.getList(projectMasterChipConfigIdList);
                List<Files> fileList = filesService.getFileList(FileRelationTypeEnum.PROJECT_CHIP_CLOCK_PARAMETER.getRelationTypeId(), projectMasterChipConfigIdList);
                for(int i = 0; i < masterChipNodeDataList.size();i++){
                    JSONObject masterChipNodeData = masterChipNodeDataList.get(i);
                    JSONObject data = masterChipNodeData.getJSONObject("data");
                    String masterChipComponentId = masterChipComponentIdList.get(i);
                    ProjectMasterChipConfig projectMasterChipConfig = projectMasterChipConfigList.stream().filter(p -> masterChipComponentId.equals(p.getComponentId())).findFirst().orElse(null);
                    JSONObject configData = new JSONObject();
                    if(projectMasterChipConfig != null){
                        List<ProjectMasterChipClockParameter> projectMasterChipClockParameterListByConfigId = projectMasterChipClockParameterList.stream().filter(p -> projectMasterChipConfig.getProjectMasterChipConfigId().equals(p.getProjectMasterChipConfigId())).collect(Collectors.toList());
                        List<JSONObject> clockParameters = new ArrayList<>();
                        for(ProjectMasterChipClockParameter projectMasterChipClockParameter : projectMasterChipClockParameterListByConfigId){
                            JSONObject projectMasterChipClockParameterData = new JSONObject();
                            projectMasterChipClockParameterData.put("projectMasterChipClockParameterId",projectMasterChipClockParameter.getProjectMasterChipClockParameterId());
                            projectMasterChipClockParameterData.put("parameterName",projectMasterChipClockParameter.getParameterName());
                            projectMasterChipClockParameterData.put("dataType",projectMasterChipClockParameter.getDataType());
                            projectMasterChipClockParameterData.put("validValues",projectMasterChipClockParameter.getValidValues());
                            projectMasterChipClockParameterData.put("defaultValue",projectMasterChipClockParameter.getDefaultValue());
                            projectMasterChipClockParameterData.put("value",projectMasterChipClockParameter.getValue());
                            projectMasterChipClockParameterData.put("symbol",projectMasterChipClockParameter.getSymbol());
                            projectMasterChipClockParameterData.put("dependencies",projectMasterChipClockParameter.getDependencies());
                            clockParameters.add(projectMasterChipClockParameterData);
                        }
                        configData.fluentPut("clockParameters",clockParameters);
                        configData.fluentPut("projectMasterChipConfigId",projectMasterChipConfig.getProjectMasterChipConfigId());
                        List<Files> fileListByConfigId = fileList.stream().filter(f -> projectMasterChipConfig.getProjectMasterChipConfigId().equals(f.getRelationId())).collect(Collectors.toList());
                        List<JSONObject> clockParameterFiles = new ArrayList<>();
                        for(Files file : fileListByConfigId){
                            JSONObject fileData = new JSONObject();
                            fileData.fluentPut("fileId",file.getFileId())
                                    .fluentPut("fileName",file.getFileName())
                                    .fluentPut("fileType",file.getFileType())
                                    .fluentPut("path",file.getPath());
                            clockParameterFiles.add(fileData);
                        }
                        configData.fluentPut("clockParameterFiles",clockParameterFiles);
                        data.fluentPut("clockParameterFilesBase64",fileListByConfigId.isEmpty() ? "" : FileUtils.fileToBase64(baseFilePath + fileListByConfigId.get(0).getPath().replaceFirst("uploads/", "")));
                    }
                    data.fluentPut("configData",configData);
                }
            }
            if(content.getJSONArray("edges") != null){
                JSONArray edges = content.getJSONArray("edges");
                List<String> edgeIdList = new ArrayList<>();
                for(int i = 0; i < edges.size();i++){
                    JSONObject edgeData = edges.getJSONObject(i);
                    edgeIdList.add(edgeData.getString("id"));
                }
                List<ProjectSlaveChipConfig> projectSlaveChipConfigList = projectSlaveChipConfigService.getList(edgeIdList);
                List<Integer> projectSlaveChipConfigIdList = projectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getProjectSlaveChipConfigId).collect(Collectors.toList());
                List<ProjectSlaveChipConfigInterface> projectSlaveChipConfigInterfaceList = projectSlaveChipConfigInterfaceService.getList(projectSlaveChipConfigIdList);
                List<ProjectSlaveChipConfigInterfacePin> projectSlaveChipConfigInterfacePinList = projectSlaveChipConfigInterfacePinService.getList(projectSlaveChipConfigIdList);
                List<ProjectSlaveChipConfigInterfacePinParameter> projectSlaveChipConfigInterfacePinParameterList = projectSlaveChipConfigInterfacePinParameterService.getList(projectSlaveChipConfigIdList);
                List<ProjectSlaveChipConfigInterfaceParameter> projectSlaveChipConfigInterfaceParameterList = projectSlaveChipConfigInterfaceParameterService.getList(projectSlaveChipConfigIdList);
                Set<Integer> driverLibraryIds = projectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getDriverLibraryId).collect(Collectors.toSet());
                List<JSONObject> formLayoutList = formLayoutService.getListByClassificationIds(FormBusinessModuleEnum.SLAVE_CHIP_PARAMETER.getModuleId(),driverLibraryIds);
                List<JSONObject> formPropertyList = formPropertyService.matchMultipleInstance(FormBusinessModuleEnum.SLAVE_CHIP_PARAMETER.getModuleId(),driverLibraryIds);
                for(int i = 0; i < edges.size();i++){
                    JSONObject edgeData = edges.getJSONObject(i);
                    JSONObject data = edgeData.getJSONObject("data");
                    JSONObject configData = new JSONObject();
                    ProjectSlaveChipConfig projectSlaveChipConfig = projectSlaveChipConfigList.stream().filter(p -> edgeData.getString("id").equals(p.getComponentId())).findFirst().orElse(null);
                    configData.fluentPut("controlModeName",projectSlaveChipConfig == null || projectSlaveChipConfig.getControlModeName() == null ? "" : projectSlaveChipConfig.getControlModeName());
                    if(projectSlaveChipConfig != null){
                        List<ProjectSlaveChipConfigInterface> projectSlaveChipConfigInterfaceListByConfigId = projectSlaveChipConfigInterfaceList.stream().filter(p -> projectSlaveChipConfig.getProjectSlaveChipConfigId().equals(p.getProjectSlaveChipConfigId())).collect(Collectors.toList());
                        List<ProjectSlaveChipConfigInterfacePin> projectSlaveChipConfigInterfacePinListByConfigId = projectSlaveChipConfigInterfacePinList.stream().filter(p -> projectSlaveChipConfig.getProjectSlaveChipConfigId().equals(p.getProjectSlaveChipConfigId())).collect(Collectors.toList());
                        List<ProjectSlaveChipConfigInterfaceParameter> projectSlaveChipConfigInterfaceParameterListByConfigId = projectSlaveChipConfigInterfaceParameterList.stream().filter(p -> projectSlaveChipConfig.getProjectSlaveChipConfigId().equals(p.getProjectSlaveChipConfigId())).collect(Collectors.toList());
                        List<ProjectSlaveChipConfigInterfacePinParameter> projectSlaveChipConfigInterfacePinParameterListByConfigId = projectSlaveChipConfigInterfacePinParameterList.stream().filter(p -> projectSlaveChipConfig.getProjectSlaveChipConfigId().equals(p.getProjectSlaveChipConfigId())).collect(Collectors.toList());
                        List<JSONObject> interfaceList = new ArrayList<>();
                        for(ProjectSlaveChipConfigInterface projectSlaveChipConfigInterface : projectSlaveChipConfigInterfaceListByConfigId){
                            JSONObject interfaceData = new JSONObject();
                            interfaceData.fluentPut("projectSlaveChipConfigInterfaceId",projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId())
                                    .fluentPut("slaveChipControlModeInterfaceId",projectSlaveChipConfigInterface.getSlaveChipControlModeInterfaceId())
                                    .fluentPut("slaveChipInterfaceName",projectSlaveChipConfigInterface.getSlaveChipInterfaceName() == null ? "" : projectSlaveChipConfigInterface.getSlaveChipInterfaceName())
                                    .fluentPut("slaveChipInterfaceDescription",projectSlaveChipConfigInterface.getSlaveChipInterfaceDescription() == null ? "" : projectSlaveChipConfigInterface.getSlaveChipInterfaceDescription())
                                    .fluentPut("slaveChipInterfaceType",projectSlaveChipConfigInterface.getSlaveChipInterfaceType() == null ? "" : projectSlaveChipConfigInterface.getSlaveChipInterfaceType())
                                    .fluentPut("slaveChipInterfaceTypeName",projectSlaveChipConfigInterface.getSlaveChipInterfaceTypeName() == null ? "" : projectSlaveChipConfigInterface.getSlaveChipInterfaceTypeName())
                                    .fluentPut("masterChipResourceName",projectSlaveChipConfigInterface.getMasterChipResourceName() == null ? "" : projectSlaveChipConfigInterface.getMasterChipResourceName());
                            List<ProjectSlaveChipConfigInterfacePin> projectSlaveChipConfigInterfacePinListByInterfaceId = projectSlaveChipConfigInterfacePinListByConfigId.stream().filter(p -> projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId().equals(p.getProjectSlaveChipConfigInterfaceId())).collect(Collectors.toList());
                            List<ProjectSlaveChipConfigInterfacePinParameter> projectSlaveChipConfigInterfacePinParameterListByInterfaceId = projectSlaveChipConfigInterfacePinParameterListByConfigId.stream().filter(p -> projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId().equals(p.getProjectSlaveChipConfigInterfaceId())).collect(Collectors.toList());
                            List<JSONObject> pinList = new ArrayList<>();
                            for(ProjectSlaveChipConfigInterfacePin projectSlaveChipConfigInterfacePin : projectSlaveChipConfigInterfacePinListByInterfaceId){
                                JSONObject pinData = new JSONObject();
                                pinData.fluentPut("projectSlaveChipConfigInterfacePinId",projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigInterfacePinId())
                                        .fluentPut("masterChipPinName",projectSlaveChipConfigInterfacePin.getMasterChipPinName() == null ? "" : projectSlaveChipConfigInterfacePin.getMasterChipPinName())
                                        .fluentPut("masterChipPinCode",projectSlaveChipConfigInterfacePin.getMasterChipPinCode() == null ? "" : projectSlaveChipConfigInterfacePin.getMasterChipPinCode());
                                List<ProjectSlaveChipConfigInterfacePinParameter> projectSlaveChipConfigInterfacePinParameterListByPinId = projectSlaveChipConfigInterfacePinParameterListByInterfaceId.stream().filter(p -> projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigInterfacePinId().equals(p.getProjectSlaveChipConfigInterfacePinId())).collect(Collectors.toList());
                                List<JSONObject> parameterList = new ArrayList<>();
                                for(ProjectSlaveChipConfigInterfacePinParameter projectSlaveChipConfigInterfacePinParameter : projectSlaveChipConfigInterfacePinParameterListByPinId){
                                    JSONObject parameterData = new JSONObject();
                                    parameterData.put("masterChipInterfacePinParameterId",projectSlaveChipConfigInterfacePinParameter.getMasterChipInterfacePinParameterId());
                                    parameterData.put("parameterName",projectSlaveChipConfigInterfacePinParameter.getParameterName());
                                    parameterData.put("dataType",projectSlaveChipConfigInterfacePinParameter.getDataType());
                                    parameterData.put("validValues",projectSlaveChipConfigInterfacePinParameter.getValidValues());
                                    parameterData.put("symbol",projectSlaveChipConfigInterfacePinParameter.getSymbol());
                                    parameterData.put("dependencies",projectSlaveChipConfigInterfacePinParameter.getDependencies());
                                    parameterData.put("value",projectSlaveChipConfigInterfacePinParameter.getValue());
                                    parameterList.add(parameterData);
                                }
                                pinData.fluentPut("parameterList",parameterList);
                                pinList.add(pinData);
                            }
                            List<ProjectSlaveChipConfigInterfaceParameter> projectSlaveChipConfigInterfaceParameterListByInterfaceId = projectSlaveChipConfigInterfaceParameterListByConfigId.stream().filter(p -> projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId().equals(p.getProjectSlaveChipConfigInterfaceId())).collect(Collectors.toList());
                            List<JSONObject> parameterList = new ArrayList<>();
                            for(ProjectSlaveChipConfigInterfaceParameter projectSlaveChipConfigInterfaceParameter : projectSlaveChipConfigInterfaceParameterListByInterfaceId){
                                JSONObject parameterData = new JSONObject();
                                parameterData.fluentPut("projectSlaveChipConfigInterfaceParameterId",projectSlaveChipConfigInterfaceParameter.getProjectSlaveChipConfigInterfaceParameterId())
                                        .fluentPut("parameterName",projectSlaveChipConfigInterfaceParameter.getParameterName())
                                        .fluentPut("symbol",projectSlaveChipConfigInterfaceParameter.getSymbol())
                                        .fluentPut("dataType",projectSlaveChipConfigInterfaceParameter.getDataType())
                                        .fluentPut("validValues",projectSlaveChipConfigInterfaceParameter.getValidValues())
                                        .fluentPut("value",projectSlaveChipConfigInterfaceParameter.getValue());
                                parameterList.add(parameterData);
                            }
                            interfaceData.fluentPut("pinList",pinList)
                                    .fluentPut("parameterList",parameterList);
                            interfaceList.add(interfaceData);
                        }
                        configData.fluentPut("interfaceList",interfaceList);
                        configData.fluentPut("projectSlaveChipConfigId",projectSlaveChipConfig.getProjectSlaveChipConfigId());
                        JSONObject formLayout = formLayoutList.stream().filter(json ->json.getInteger("classificationId").equals(projectSlaveChipConfig.getDriverLibraryId())).findFirst().orElse(null);
                        configData.put("formLayout",formLayout == null ? new JSONObject() : formLayout.getJSONObject("components"));
                        List<JSONObject> propertyList = formPropertyList.stream().filter(json ->json.getString("businessKey").equals(projectSlaveChipConfig.getProjectSlaveChipConfigId().toString())).collect(Collectors.toList());
                        JSONArray formProperties = formPropertyService.propertyListToArray(propertyList);
                        configData.put("formProperties",formProperties);
                    }
                    data.fluentPut("configData",configData);
                }
            }
        }
        if(layoutContent == null){
            layoutContent = new JSONObject();
            JSONObject content = new JSONObject();
            content.fluentPut("edges",new ArrayList<>())
                    .fluentPut("nodes",new ArrayList<>());
            layoutContent.fluentPut("content",content)
                    .fluentPut("x",0)
                    .fluentPut("y",0);
        }
        JSONObject returnData = new JSONObject();
        returnData.fluentPut("projectId",project.getProjectId())
                .fluentPut("name",project.getName() == null ? "" : project.getName())
                .fluentPut("layoutContent",layoutContent);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,returnData);
    }

    /**
     * 保存配置
     * @param webData
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject saveConfig(JSONObject webData,Users user){
        Project project = new Project();
        project.setProjectId(webData.getInteger("projectId"));
        JSONObject layoutContent = webData.getJSONObject("layoutContent");
        JSONObject content = layoutContent.getJSONObject("content");
        JSONArray nodes = content.getJSONArray("nodes");
        JSONArray edges = content.getJSONArray("edges");
        List<ProjectMasterChipConfig> allProjectMasterChipConfigList = new ArrayList<>();
        List<ProjectMasterChipConfig> updateProjectMasterChipConfigList = new ArrayList<>();
        List<ProjectMasterChipConfig> addProjectMasterChipConfigList = new ArrayList<>();
        List<JSONArray> copyClockFileList = new ArrayList<>();
        List<JSONObject> masterNodeDataList = new ArrayList<>();
        List<JSONObject> slaveNodeDataList = new ArrayList<>();
        List<ProjectMasterChipConfig> oldProjectMasterChipConfigList = projectMasterChipConfigService.findByProperty(ProjectMasterChipConfig::getProjectId, project.getProjectId());
        List<Integer> oldProjectMasterChipConfigIdList = oldProjectMasterChipConfigList.stream().map(ProjectMasterChipConfig::getProjectMasterChipConfigId).collect(Collectors.toList());
        List<Integer> updateProjectMasterChipConfigIdList = new ArrayList<>();
        for(int i = 0; i < nodes.size();i++){
            JSONObject nodeData = nodes.getJSONObject(i);
            JSONObject data = nodeData.getJSONObject("data");
            if(ChipTypeEnum.MASTER.getType().equals(data.getInteger("chipType"))){
                ProjectMasterChipConfig projectMasterChipConfig = new ProjectMasterChipConfig();
                JsonConverter<ProjectMasterChipConfig> projectMasterChipConfigJsonConverter = new JsonConverter<>();
                projectMasterChipConfig = projectMasterChipConfigJsonConverter.convert(data, projectMasterChipConfig);
                projectMasterChipConfig.setChipId(data.getInteger("masterChipId"));
                projectMasterChipConfig.setProjectId(project.getProjectId());
                projectMasterChipConfig.setComponentId(nodeData.getString("id"));
                if(oldProjectMasterChipConfigIdList.contains(projectMasterChipConfig.getProjectMasterChipConfigId())){
                    updateProjectMasterChipConfigIdList.add(projectMasterChipConfig.getProjectMasterChipConfigId());
                    updateProjectMasterChipConfigList.add(projectMasterChipConfig);
                }else{
                    addProjectMasterChipConfigList.add(projectMasterChipConfig);
                    JSONObject configData = data.getJSONObject("configData");
                    copyClockFileList.add(configData.getJSONArray("clockParameterFiles"));
                }
                allProjectMasterChipConfigList.add(projectMasterChipConfig);
                masterNodeDataList.add(nodeData);
            }else if(ChipTypeEnum.SLAVE.getType().equals(data.getInteger("chipType"))){
                slaveNodeDataList.add(nodeData);
            }
        }
        List<Integer> deleteProjectMasterChipConfigIdList = new ArrayList<>();
        for(ProjectMasterChipConfig projectMasterChipConfig : oldProjectMasterChipConfigList){
            if(!updateProjectMasterChipConfigIdList.contains(projectMasterChipConfig.getProjectMasterChipConfigId())){
                deleteProjectMasterChipConfigIdList.add(projectMasterChipConfig.getProjectMasterChipConfigId());
            }
        }
        if(!addProjectMasterChipConfigList.isEmpty()){
            projectMasterChipConfigService.insertBatchSomeColumn(addProjectMasterChipConfigList);
        }
        if(!updateProjectMasterChipConfigList.isEmpty()){
            projectMasterChipConfigService.updateBatchById(updateProjectMasterChipConfigList);
        }
        if(!deleteProjectMasterChipConfigIdList.isEmpty()){
            projectMasterChipConfigService.removeByIds(deleteProjectMasterChipConfigIdList);
        }
        for(int i =0;i < addProjectMasterChipConfigList.size();i++){
            ProjectMasterChipConfig projectMasterChipConfig = addProjectMasterChipConfigList.get(i);
            JSONArray copyClockFile = copyClockFileList.get(i);
            filesService.copyFiles(copyClockFile,user.getUserId(), FileRelationTypeEnum.PROJECT_CHIP_CLOCK_PARAMETER.getRelationTypeId(),projectMasterChipConfig.getProjectMasterChipConfigId());
        }
        List<ProjectMasterChipClockParameter> oldProjectMasterChipClockParameterList = projectMasterChipClockParameterService.getList(oldProjectMasterChipConfigIdList);
        List<Integer> oldProjectMasterChipClockParameterIdList = oldProjectMasterChipClockParameterList.stream().map(ProjectMasterChipClockParameter::getProjectMasterChipClockParameterId).collect(Collectors.toList());
        List<ProjectMasterChipClockParameter> updateProjectMasterChipClockParameterList = new ArrayList<>();
        List<ProjectMasterChipClockParameter> addProjectMasterChipClockParameterList = new ArrayList<>();
        for(int i = 0; i < masterNodeDataList.size();i++) {
            JSONObject masterNodeData = masterNodeDataList.get(i);
            ProjectMasterChipConfig projectMasterChipConfig = allProjectMasterChipConfigList.get(i);
            JSONObject data = masterNodeData.getJSONObject("data");
            JSONObject configData = data.getJSONObject("configData");
            // 如果 configData 为空，则需要填充 configData
            if (configData.isEmpty()) {
                // 根据 ProjectID 查找对应的 project
                JSONArray masterChipClockParameters = new JSONArray();
                JSONObject clockParameterInitResult=getMasterChipClockParameters(data.getInteger("chipId"), masterChipClockParameters);
                if (!clockParameterInitResult.getBoolean(APP.SUCCESS)) {//将规则校验结果返回
                    return clockParameterInitResult;
                }
                // 如果 masterChipClockParameters 依旧为空则抛出失败
                if (masterChipClockParameters.isEmpty()) {
                    return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM, "找不到对应的主芯片时钟参数，请检查传入的 masterChipId 是否有误");
                }
                configData
                        .fluentPut("clockParameters", masterChipClockParameters)
                        .fluentPut("clockParameterFiles", new JSONArray());
                // 如果 data 下也没有clockParameters则也加入到数据库中
                if (data.getJSONArray("clockParameters") == null) {
                    data.fluentPut("clockParameters", masterChipClockParameters);
                }
            } else {
                //web填充做依赖关系校验
                // 获取时钟参数
                JSONArray clockParameters = configData.getJSONArray("clockParameters");
                Map<String, JSONObject> clockParametersMap = new HashMap<>();
                JSONObject requestClockParameters = new JSONObject();

                // 使用流式 API 处理 clockParameters
                clockParameters.stream()
                        .map(JSONObject.class::cast)
                        .forEach(parameterData -> {
                            requestClockParameters.fluentPut(parameterData.getString("symbol"), parameterData.getString("value"));
                            clockParametersMap.put(parameterData.getString("symbol"), parameterData);
                        });

                JSONObject requestParam = new JSONObject()
                        .fluentPut("chipId", data.getInteger("chipId"))
                        .fluentPut("ruleSetType", RuleSetTypeEnum.CLOCK_CONFIGURATION.getId())
                        .fluentPut("parameterData", requestClockParameters);

                JSONObject response = dependencyRuleCheck(requestParam);

                if (!response.getBoolean(APP.SUCCESS)) {
                    return response;
                }
                JSONObject responseData = response.getJSONObject(APP.DATA);
                List<String> matchConditionKeyList = responseData.getJSONArray("matchConditionKeyList").toJavaList(String.class);
                //将不匹配的时钟参数的value属性删除
                clockParametersMap.keySet().stream()
                        .filter(key -> !matchConditionKeyList.contains(key))
                        .forEach(key -> clockParametersMap.get(key).remove("value"));
            }
            JSONArray clockParameters = configData.getJSONArray("clockParameters");
            for(int j = 0;j < clockParameters.size();j++){
                JSONObject parameterData = clockParameters.getJSONObject(j);
                ProjectMasterChipClockParameter projectMasterChipClockParameter = new ProjectMasterChipClockParameter();
                JsonConverter<ProjectMasterChipClockParameter> parameterJsonConverter = new JsonConverter<>();
                projectMasterChipClockParameter = parameterJsonConverter.convert(parameterData, projectMasterChipClockParameter);
                projectMasterChipClockParameter.setProjectMasterChipConfigId(projectMasterChipConfig.getProjectMasterChipConfigId());
                if(oldProjectMasterChipClockParameterIdList.contains(projectMasterChipClockParameter.getProjectMasterChipClockParameterId())){
                    projectMasterChipClockParameter.setUpdateUserId(user.getUserId());
                    updateProjectMasterChipClockParameterList.add(projectMasterChipClockParameter);
                }else{
                    projectMasterChipClockParameter.setCreatorId(user.getUserId());
                    addProjectMasterChipClockParameterList.add(projectMasterChipClockParameter);
                }
            }
            data.remove("configData");
        }

        List<Integer> updateProjectMasterChipClockParameterIdList = updateProjectMasterChipClockParameterList.stream().map(ProjectMasterChipClockParameter::getProjectMasterChipClockParameterId).collect(Collectors.toList());
        List<Integer> deleteProjectMasterChipClockParameterIdList = new ArrayList<>();
        for(Integer oldProjectMasterChipClockParameterId : oldProjectMasterChipClockParameterIdList){
            if(!updateProjectMasterChipClockParameterIdList.contains(oldProjectMasterChipClockParameterId)){
                deleteProjectMasterChipClockParameterIdList.add(oldProjectMasterChipClockParameterId);
            }
        }
        if(!addProjectMasterChipClockParameterList.isEmpty()){
            projectMasterChipClockParameterService.saveBatch(addProjectMasterChipClockParameterList);
        }
        if(!updateProjectMasterChipClockParameterList.isEmpty()){
            projectMasterChipClockParameterService.updateBatchById(updateProjectMasterChipClockParameterList);
        }
        if(!deleteProjectMasterChipClockParameterIdList.isEmpty()){
            projectMasterChipClockParameterService.removeByIds(deleteProjectMasterChipClockParameterIdList);
        }
        List<Integer> masterChipIdList = new ArrayList<>();
        List<Integer> slaveChipIdList = new ArrayList<>();
        for(int i = 0; i < edges.size();i++) {
            JSONObject edgeData = edges.getJSONObject(i);
            JSONObject data = edgeData.getJSONObject("data");
            Integer slaveChipId = data.getInteger("slaveChipId");
            Integer masterChipId = data.getInteger("masterChipId");
            masterChipIdList.add(masterChipId);
            slaveChipIdList.add(slaveChipId);
        }
        List<ProjectSlaveChipConfig> allProjectSlaveChipConfigList = new ArrayList<>();
        List<ProjectSlaveChipConfig> addProjectSlaveChipConfigList = new ArrayList<>();
        List<ProjectSlaveChipConfig> updateProjectSlaveChipConfigList = new ArrayList<>();
        List<ChipControlMode> controlModeList = chipControlModeService.getList(slaveChipIdList);
        List<Integer> updateProjectSlaveChipConfigIdList = new ArrayList<>();
        List<ProjectSlaveChipConfig> oldProjectSlaveChipConfigList = projectSlaveChipConfigService.findByProperty(ProjectSlaveChipConfig::getProjectId, project.getProjectId());
        List<Integer> oldProjectSlaveChipConfigIdList = oldProjectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getProjectSlaveChipConfigId).collect(Collectors.toList());
        List<JSONArray> formPropertyList = new ArrayList<>();
        for(int i = 0; i < edges.size();i++){
            JSONObject edgeData = edges.getJSONObject(i);
            JSONObject data = edgeData.getJSONObject("data");
            String id = edgeData.getString("id");
            JSONObject configData = data.getJSONObject("configData");
            Integer slaveChipId = data.getInteger("slaveChipId");
            Integer driverLibraryId = data.getInteger("driverLibraryId");
            String controlModeName = configData.getString("controlModeName");
            JSONArray formProperties = configData.getJSONArray("formProperties");
            ProjectSlaveChipConfig projectSlaveChipConfig = new ProjectSlaveChipConfig();
            JsonConverter<ProjectSlaveChipConfig> projectSlaveChipConfigJsonConverter = new JsonConverter<>();
            projectSlaveChipConfig = projectSlaveChipConfigJsonConverter.convert(configData, projectSlaveChipConfig);
            ChipControlMode chipControlMode = controlModeList.stream().filter(c -> slaveChipId.equals(c.getChipId()) && controlModeName != null && controlModeName.equals(c.getName())).findFirst().orElse(null);
            if(chipControlMode != null){
                projectSlaveChipConfig.setControlModeId(chipControlMode.getControlModeId());
            }
            projectSlaveChipConfig.setComponentId(id);
            projectSlaveChipConfig.setProjectId(project.getProjectId());
            projectSlaveChipConfig.setChipId(slaveChipId);
            projectSlaveChipConfig.setDriverLibraryId(driverLibraryId);
            if(oldProjectSlaveChipConfigIdList.contains(projectSlaveChipConfig.getProjectSlaveChipConfigId())){
                projectSlaveChipConfig.setUpdateUserId(user.getUserId());
                updateProjectSlaveChipConfigIdList.add(projectSlaveChipConfig.getProjectSlaveChipConfigId());
                updateProjectSlaveChipConfigList.add(projectSlaveChipConfig);
            }else{
                projectSlaveChipConfig.setCreatorId(user.getUserId());
                addProjectSlaveChipConfigList.add(projectSlaveChipConfig);
            }
            allProjectSlaveChipConfigList.add(projectSlaveChipConfig);
            formPropertyList.add(formProperties);

        }
        if(!addProjectSlaveChipConfigList.isEmpty()){
            projectSlaveChipConfigService.insertBatchSomeColumn(addProjectSlaveChipConfigList);
        }
        if(!updateProjectSlaveChipConfigList.isEmpty()){
            projectSlaveChipConfigService.updateBatchById(updateProjectSlaveChipConfigList);
        }

        //保存芯片参数表单属性
        List<String> projectSlaveChipConfigIdList = allProjectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getProjectSlaveChipConfigId).map(Object::toString).collect(Collectors.toList());
        List<Integer> projectSlaveDriverLibraryIdList = allProjectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getDriverLibraryId).collect(Collectors.toList());
        formPropertyService.batchSaveOrUpdateFormProperty(formPropertyList,projectSlaveChipConfigIdList,projectSlaveDriverLibraryIdList,FormBusinessModuleEnum.SLAVE_CHIP_PARAMETER.getModuleId());

        List<Integer> deleteProjectSlaveChipConfigIdList = new ArrayList<>();
        for(ProjectSlaveChipConfig projectSlaveChipConfig : oldProjectSlaveChipConfigList){
            if(!updateProjectSlaveChipConfigIdList.contains(projectSlaveChipConfig.getProjectSlaveChipConfigId())){
                deleteProjectSlaveChipConfigIdList.add(projectSlaveChipConfig.getProjectSlaveChipConfigId());
            }
        }
        if(!deleteProjectSlaveChipConfigIdList.isEmpty()){
            projectSlaveChipConfigService.removeByIds(deleteProjectSlaveChipConfigIdList);
            formPropertyService.deleteBatchByBusinessKeys(deleteProjectSlaveChipConfigIdList.stream().map(Object::toString).collect(Collectors.toList()), FormBusinessModuleEnum.SLAVE_CHIP_PARAMETER.getModuleId());
        }
        List<ProjectSlaveChipConfigInterface> oldProjectSlaveChipConfigInterfaceList = projectSlaveChipConfigInterfaceService.getList(oldProjectSlaveChipConfigIdList);
        List<Integer> oldProjectSlaveChipConfigInterfaceIdList = oldProjectSlaveChipConfigInterfaceList.stream().map(ProjectSlaveChipConfigInterface::getProjectSlaveChipConfigInterfaceId).collect(Collectors.toList());
        List<ProjectSlaveChipConfigInterface> allProjectSlaveChipConfigInterfaceList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterface> addProjectSlaveChipConfigInterfaceList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterface> updateProjectSlaveChipConfigInterfaceList = new ArrayList<>();
        List<JSONObject> projectSlaveChipConfigInterfaceDataList = new ArrayList<>();
        List<ChipInterface> chipInterfaceList = chipInterfaceService.getList(masterChipIdList);
        List<Integer> controlModeIdList = controlModeList.stream().map(ChipControlMode::getControlModeId).collect(Collectors.toList());
        List<ChipControlModeInterface> chipControlModeInterfaceList = chipControlModeInterfaceService.getList(controlModeIdList);
        List<Integer> chipControlModeInterfaceIdList = chipControlModeInterfaceList.stream().map(ChipControlModeInterface::getControlModeInterfaceId).collect(Collectors.toList());
        List<ChipControlModeInterfaceType> chipControlModeInterfaceTypeList = chipControlModeInterfaceTypeService.getList(chipControlModeInterfaceIdList);
        for(int i = 0; i < edges.size();i++) {
            JSONObject edgeData = edges.getJSONObject(i);
            ProjectSlaveChipConfig projectSlaveChipConfig = allProjectSlaveChipConfigList.get(i);
            JSONObject data = edgeData.getJSONObject("data");
            JSONObject configData = data.getJSONObject("configData");
            JSONArray interfaceList = configData.getJSONArray("interfaceList");
            if(interfaceList == null || interfaceList.isEmpty()){
                continue;
            }
            Integer masterChipId = data.getInteger("masterChipId");
            for(int j = 0; j < interfaceList.size();j++){
                JSONObject interfaceData = interfaceList.getJSONObject(j);
                ProjectSlaveChipConfigInterface projectSlaveChipConfigInterface = new ProjectSlaveChipConfigInterface();
                JsonConverter<ProjectSlaveChipConfigInterface> projectSlaveChipConfigInterfaceJsonConverter = new JsonConverter<>();
                projectSlaveChipConfigInterface = projectSlaveChipConfigInterfaceJsonConverter.convert(interfaceData, projectSlaveChipConfigInterface);
                if(oldProjectSlaveChipConfigInterfaceIdList.contains(projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId())){
                    projectSlaveChipConfigInterface.setUpdateUserId(user.getUserId());
                    updateProjectSlaveChipConfigInterfaceList.add(projectSlaveChipConfigInterface);
                }else{
                    projectSlaveChipConfigInterface.setCreatorId(user.getUserId());
                    addProjectSlaveChipConfigInterfaceList.add(projectSlaveChipConfigInterface);
                }
                ChipInterface chipInterface = null;
                if(StringUtils.isNotBlank(interfaceData.getString("masterChipResourceName"))){
                    String masterChipResourceName = interfaceData.getString("masterChipResourceName");
                    chipInterface = chipInterfaceList.stream().filter(c -> masterChipId.equals(c.getChipId()) && masterChipResourceName.equals(c.getResourceName())).findFirst().orElse(null);
                }
               if(chipInterface != null){
                    projectSlaveChipConfigInterface.setMasterChipInterfaceId(chipInterface.getInterfaceId());
                }
                ProjectSlaveChipConfigInterface finalProjectSlaveChipConfigInterface = projectSlaveChipConfigInterface;
                List<ChipControlModeInterfaceType> chipControlModeInterfaceTypeListByInterfaceId = chipControlModeInterfaceTypeList.stream().filter(c -> c.getControlModeInterfaceId() != null && c.getControlModeInterfaceId().equals(finalProjectSlaveChipConfigInterface.getSlaveChipControlModeInterfaceId())).collect(Collectors.toList());
                ChipControlModeInterfaceType chipControlModeInterfaceType = chipControlModeInterfaceTypeListByInterfaceId.stream().filter(c -> c.getInterfaceType().equals(interfaceData.getString("slaveChipInterfaceTypeName"))).findFirst().orElse(null);
                if(chipControlModeInterfaceType != null){
                    projectSlaveChipConfigInterface.setSlaveChipInterfaceTypeId(chipControlModeInterfaceType.getId());
                }
                projectSlaveChipConfigInterface.setProjectSlaveChipConfigId(projectSlaveChipConfig.getProjectSlaveChipConfigId());
                allProjectSlaveChipConfigInterfaceList.add(projectSlaveChipConfigInterface);
                projectSlaveChipConfigInterfaceDataList.add(interfaceData);
            }
        }
        List<Integer> updateProjectSlaveChipConfigInterfaceIdList = updateProjectSlaveChipConfigInterfaceList.stream().map(ProjectSlaveChipConfigInterface::getProjectSlaveChipConfigInterfaceId).collect(Collectors.toList());
        List<Integer> deleteProjectSlaveChipConfigInterfaceIdList = new ArrayList<>();
        for(ProjectSlaveChipConfigInterface oldProjectSlaveChipConfigInterface : oldProjectSlaveChipConfigInterfaceList){
            if(!updateProjectSlaveChipConfigInterfaceIdList.contains(oldProjectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId())){
                deleteProjectSlaveChipConfigInterfaceIdList.add(oldProjectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId());
            }
        }
        if(!addProjectSlaveChipConfigInterfaceList.isEmpty()){
            projectSlaveChipConfigInterfaceService.insertBatchSomeColumn(addProjectSlaveChipConfigInterfaceList);
        }
        if(!updateProjectMasterChipConfigList.isEmpty()){
            projectSlaveChipConfigInterfaceService.updateBatchById(updateProjectSlaveChipConfigInterfaceList);
        }
        if(!deleteProjectSlaveChipConfigInterfaceIdList.isEmpty()){
            projectSlaveChipConfigInterfaceService.removeByIds(deleteProjectSlaveChipConfigInterfaceIdList);
        }
        List<ChipPin> chipPinList = chipPinService.getList(masterChipIdList);
        List<ProjectSlaveChipConfigInterfacePin> oldProjectSlaveChipConfigInterfacePinList = projectSlaveChipConfigInterfacePinService.getList(oldProjectSlaveChipConfigIdList);
        List<Integer> oldProjectSlaveChipConfigInterfacePinIdList = oldProjectSlaveChipConfigInterfacePinList.stream().map(ProjectSlaveChipConfigInterfacePin::getProjectSlaveChipConfigInterfacePinId).collect(Collectors.toList());
        List<ProjectSlaveChipConfigInterfaceParameter> oldProjectSlaveChipConfigInterfaceParameterList = projectSlaveChipConfigInterfaceParameterService.getList(oldProjectSlaveChipConfigIdList);
        List<Integer> oldProjectSlaveChipConfigInterfaceParameterIdList = oldProjectSlaveChipConfigInterfaceParameterList.stream().map(ProjectSlaveChipConfigInterfaceParameter::getProjectSlaveChipConfigInterfaceParameterId).collect(Collectors.toList());
        List<JSONObject> allPinDataList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterfacePin> allProjectSlaveChipConfigInterfacePinList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterfacePin> addProjectSlaveChipConfigInterfacePinList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterfacePin> updateProjectSlaveChipConfigInterfacePinList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterfacePinParameter> addProjectSlaveChipConfigInterfacePinParameterList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterfacePinParameter> updateProjectSlaveChipConfigInterfacePinParameterList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterfaceParameter> addProjectSlaveChipConfigInterfaceParameterList = new ArrayList<>();
        List<ProjectSlaveChipConfigInterfaceParameter> updateProjectSlaveChipConfigInterfaceParameterList = new ArrayList<>();
        for(int i = 0;i < projectSlaveChipConfigInterfaceDataList.size();i++){
            JSONObject projectSlaveChipConfigInterfaceData = projectSlaveChipConfigInterfaceDataList.get(i);
            ProjectSlaveChipConfigInterface projectSlaveChipConfigInterface = allProjectSlaveChipConfigInterfaceList.get(i);
            if(projectSlaveChipConfigInterfaceData.getJSONArray("pinList") != null){
                JSONArray pinList = projectSlaveChipConfigInterfaceData.getJSONArray("pinList");
                for(int j = 0;j < pinList.size();j++){
                    JSONObject pinData = pinList.getJSONObject(j);
                    ProjectSlaveChipConfigInterfacePin projectSlaveChipConfigInterfacePin = new ProjectSlaveChipConfigInterfacePin();
                    JsonConverter<ProjectSlaveChipConfigInterfacePin> projectSlaveChipConfigInterfacePinJsonConverter = new JsonConverter<>();
                    projectSlaveChipConfigInterfacePin = projectSlaveChipConfigInterfacePinJsonConverter.convert(pinData, projectSlaveChipConfigInterfacePin);
                    if(oldProjectSlaveChipConfigInterfacePinIdList.contains(projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigInterfacePinId())){
                        projectSlaveChipConfigInterfacePin.setUpdateUserId(user.getUserId());
                        updateProjectSlaveChipConfigInterfacePinList.add(projectSlaveChipConfigInterfacePin);
                    }else{
                        projectSlaveChipConfigInterfacePin.setCreatorId(user.getUserId());
                        addProjectSlaveChipConfigInterfacePinList.add(projectSlaveChipConfigInterfacePin);
                    }
                    ChipPin chipPin = chipPinList.stream().filter(c -> pinData.getString("masterChipPinCode").equals(c.getPinCode())).findFirst().orElse(null);
                    if(chipPin != null){
                        projectSlaveChipConfigInterfacePin.setMasterChipPinId(chipPin.getPinId());
                    }
                    projectSlaveChipConfigInterfacePin.setProjectSlaveChipConfigId(projectSlaveChipConfigInterface.getProjectSlaveChipConfigId());
                    projectSlaveChipConfigInterfacePin.setProjectSlaveChipConfigInterfaceId(projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId());
                    allProjectSlaveChipConfigInterfacePinList.add(projectSlaveChipConfigInterfacePin);
                    allPinDataList.add(pinData);
                }
            }
            if(projectSlaveChipConfigInterfaceData.getJSONArray("parameterList") != null){
                JSONArray parameterList = projectSlaveChipConfigInterfaceData.getJSONArray("parameterList");
                for(int j = 0;j < parameterList.size();j++){
                    JSONObject parameterData = parameterList.getJSONObject(j);
                    ProjectSlaveChipConfigInterfaceParameter projectSlaveChipConfigInterfaceParameter = new ProjectSlaveChipConfigInterfaceParameter();
                    JsonConverter<ProjectSlaveChipConfigInterfaceParameter> projectSlaveChipConfigInterfacePinJsonConverter = new JsonConverter<>();
                    projectSlaveChipConfigInterfaceParameter = projectSlaveChipConfigInterfacePinJsonConverter.convert(parameterData, projectSlaveChipConfigInterfaceParameter);
                    if(oldProjectSlaveChipConfigInterfaceParameterIdList.contains(projectSlaveChipConfigInterfaceParameter.getProjectSlaveChipConfigInterfaceParameterId())){
                        projectSlaveChipConfigInterfaceParameter.setUpdateUserId(user.getUserId());
                        updateProjectSlaveChipConfigInterfaceParameterList.add(projectSlaveChipConfigInterfaceParameter);
                    }else{
                        projectSlaveChipConfigInterfaceParameter.setCreatorId(user.getUserId());
                        addProjectSlaveChipConfigInterfaceParameterList.add(projectSlaveChipConfigInterfaceParameter);
                    }
                    projectSlaveChipConfigInterfaceParameter.setProjectSlaveChipConfigId(projectSlaveChipConfigInterface.getProjectSlaveChipConfigId());
                    projectSlaveChipConfigInterfaceParameter.setProjectSlaveChipConfigInterfaceId(projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId());
                }
            }
        }
        if(!addProjectSlaveChipConfigInterfacePinList.isEmpty()){
            projectSlaveChipConfigInterfacePinService.insertBatch(addProjectSlaveChipConfigInterfacePinList);
        }
        if(!updateProjectSlaveChipConfigInterfacePinList.isEmpty()){
            projectSlaveChipConfigInterfacePinService.updateBatchById(updateProjectSlaveChipConfigInterfacePinList);
        }
        List<Integer> updateProjectSlaveChipConfigInterfacePinIdList = updateProjectSlaveChipConfigInterfacePinList.stream().map(ProjectSlaveChipConfigInterfacePin::getProjectSlaveChipConfigInterfacePinId).collect(Collectors.toList());
        List<Integer> deleteProjectSlaveChipConfigInterfacePinIdList = new ArrayList<>();
        for(ProjectSlaveChipConfigInterfacePin projectSlaveChipConfigInterfacePin : oldProjectSlaveChipConfigInterfacePinList){
            if(!updateProjectSlaveChipConfigInterfacePinIdList.contains(projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigInterfacePinId())){
                deleteProjectSlaveChipConfigInterfacePinIdList.add(projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigInterfacePinId());
            }
        }
        if(!deleteProjectSlaveChipConfigInterfacePinIdList.isEmpty()){
            projectSlaveChipConfigInterfacePinService.removeByIds(deleteProjectSlaveChipConfigInterfacePinIdList);
        }
        List<ProjectSlaveChipConfigInterfacePinParameter> oldProjectSlaveChipConfigInterfacePinParameterList = projectSlaveChipConfigInterfacePinParameterService.getList(oldProjectSlaveChipConfigIdList);
        List<Integer> oldProjectSlaveChipConfigInterfacePinParameterIdList = oldProjectSlaveChipConfigInterfacePinParameterList.stream().map(ProjectSlaveChipConfigInterfacePinParameter::getProjectSlaveChipConfigInterfacePinParameterId).collect(Collectors.toList());
        for (int i = 0; i < allPinDataList.size(); i++) {
            JSONObject pinData = allPinDataList.get(i);
            ProjectSlaveChipConfigInterfacePin projectSlaveChipConfigInterfacePin = allProjectSlaveChipConfigInterfacePinList.get(i);
            JSONArray parameterList = pinData.getJSONArray("parameterList");
            for(int parameterIndex = 0;parameterIndex < parameterList.size();parameterIndex++){
                JSONObject parameterData = parameterList.getJSONObject(parameterIndex);
                ProjectSlaveChipConfigInterfacePinParameter projectSlaveChipConfigInterfacePinParameter = new ProjectSlaveChipConfigInterfacePinParameter();
                JsonConverter<ProjectSlaveChipConfigInterfacePinParameter> parameterJsonConverter = new JsonConverter<>();
                projectSlaveChipConfigInterfacePinParameter = parameterJsonConverter.convert(parameterData, projectSlaveChipConfigInterfacePinParameter);
                projectSlaveChipConfigInterfacePinParameter.setProjectSlaveChipConfigInterfacePinId(projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigInterfacePinId());
                projectSlaveChipConfigInterfacePinParameter.setProjectSlaveChipConfigInterfaceId(projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigInterfaceId());
                projectSlaveChipConfigInterfacePinParameter.setProjectSlaveChipConfigId(projectSlaveChipConfigInterfacePin.getProjectSlaveChipConfigId());
                if(oldProjectSlaveChipConfigInterfacePinParameterIdList.contains(projectSlaveChipConfigInterfacePinParameter.getProjectSlaveChipConfigInterfacePinParameterId())){
                    projectSlaveChipConfigInterfacePinParameter.setUpdateUserId(user.getUserId());
                    updateProjectSlaveChipConfigInterfacePinParameterList.add(projectSlaveChipConfigInterfacePinParameter);
                }else{
                    projectSlaveChipConfigInterfacePinParameter.setCreatorId(user.getUserId());
                    addProjectSlaveChipConfigInterfacePinParameterList.add(projectSlaveChipConfigInterfacePinParameter);
                }
            }
        }

        if(!addProjectSlaveChipConfigInterfacePinParameterList.isEmpty()){
            projectSlaveChipConfigInterfacePinParameterService.saveBatch(addProjectSlaveChipConfigInterfacePinParameterList);
        }
        if(!updateProjectSlaveChipConfigInterfacePinParameterList.isEmpty()){
            projectSlaveChipConfigInterfacePinParameterService.updateBatchById(updateProjectSlaveChipConfigInterfacePinParameterList);
        }
        List<Integer> updateProjectSlaveChipConfigInterfacePinParameterIdList = updateProjectSlaveChipConfigInterfacePinParameterList.stream().map(ProjectSlaveChipConfigInterfacePinParameter::getProjectSlaveChipConfigInterfacePinParameterId).collect(Collectors.toList());
        List<Integer> deleteProjectSlaveChipConfigInterfacePinParameterIdList = new ArrayList<>();
        for(ProjectSlaveChipConfigInterfacePinParameter projectSlaveChipConfigInterfaceParameter : oldProjectSlaveChipConfigInterfacePinParameterList){
            if(!updateProjectSlaveChipConfigInterfacePinParameterIdList.contains(projectSlaveChipConfigInterfaceParameter.getProjectSlaveChipConfigInterfacePinParameterId())){
                deleteProjectSlaveChipConfigInterfacePinParameterIdList.add(projectSlaveChipConfigInterfaceParameter.getProjectSlaveChipConfigInterfacePinParameterId());
            }
        }
        if(!deleteProjectSlaveChipConfigInterfacePinParameterIdList.isEmpty()){
            projectSlaveChipConfigInterfacePinParameterService.removeByIds(deleteProjectSlaveChipConfigInterfacePinParameterIdList);
        }

        if(!addProjectSlaveChipConfigInterfaceParameterList.isEmpty()){
            projectSlaveChipConfigInterfaceParameterService.saveBatch(addProjectSlaveChipConfigInterfaceParameterList);
        }
        if(!updateProjectSlaveChipConfigInterfaceParameterList.isEmpty()){
            projectSlaveChipConfigInterfaceParameterService.updateBatchById(updateProjectSlaveChipConfigInterfaceParameterList);
        }
        List<Integer> updateProjectSlaveChipConfigInterfaceParameterIdList = updateProjectSlaveChipConfigInterfaceParameterList.stream().map(ProjectSlaveChipConfigInterfaceParameter::getProjectSlaveChipConfigInterfaceParameterId).collect(Collectors.toList());
        List<Integer> deleteProjectSlaveChipConfigInterfaceParameterIdList = new ArrayList<>();
        for(ProjectSlaveChipConfigInterfaceParameter projectSlaveChipConfigInterfaceParameter : oldProjectSlaveChipConfigInterfaceParameterList){
            if(!updateProjectSlaveChipConfigInterfaceParameterIdList.contains(projectSlaveChipConfigInterfaceParameter.getProjectSlaveChipConfigInterfaceParameterId())){
                deleteProjectSlaveChipConfigInterfaceParameterIdList.add(projectSlaveChipConfigInterfaceParameter.getProjectSlaveChipConfigInterfaceParameterId());
            }
        }
        if(!deleteProjectSlaveChipConfigInterfaceParameterIdList.isEmpty()){
            projectSlaveChipConfigInterfaceParameterService.removeByIds(deleteProjectSlaveChipConfigInterfaceParameterIdList);
        }
        for(int i = 0; i < edges.size();i++) {
            JSONObject edgeData = edges.getJSONObject(i);
            JSONObject data = edgeData.getJSONObject("data");
            data.remove("configData");
        }
        project.setLayoutContent(layoutContent.toJSONString());
        updateById(project);
        return JsonUtil.getSuccess("");
    }


    /**
     * 获取主芯片时钟参数
     *
     * @param masterChipId           主芯片ID
     * @param masterChipConfigData   主芯片配置数据
     */
    public JSONObject getMasterChipClockParameters(Integer masterChipId, JSONArray masterChipConfigData) {
        // 构建查询字段映射
        Map<SFunction<ChipClockParameter, ?>, Object> fieldValueMap = new HashMap<>();
        fieldValueMap.put(ChipClockParameter::getChipId, masterChipId);

        // 查询符合条件的芯片时钟参数列表
        List<ChipClockParameter> chipClockParameterList = chipClockParameterService.findByProperties(fieldValueMap);

        // 构建时钟参数请求数据对象
        JSONObject clockParameterData = new JSONObject();

        // 遍历芯片时钟参数列表
        for (ChipClockParameter chipClockParameter : chipClockParameterList) {
            // 将chipClockParameter转化为json对象
            JSONObject chipClockParameterJson = JSON.parseObject(JSON.toJSONString(chipClockParameter));
            chipClockParameterJson.put("value", chipClockParameter.getDefaultValue());
            clockParameterData.put(chipClockParameter.getSymbol(), chipClockParameter.getDefaultValue());
            // 将chipClockParameterJson添加到masterChipConfigData中
            masterChipConfigData.add(chipClockParameterJson);
        }

        // 构建请求参数对象
        JSONObject requestParameters = new JSONObject()
                .fluentPut("parameterData", clockParameterData)
                .fluentPut("chipId", masterChipId)
                .fluentPut("ruleSetType", RuleSetTypeEnum.CLOCK_CONFIGURATION.getId());

        // 执行依赖规则检查
        JSONObject resultData = dependencyRuleCheck(requestParameters);

        // 确认检查结果,若检查未成功则返回失败原因
        if (!resultData.getBoolean(APP.SUCCESS)) {
            return resultData;
        }

        // 获取依赖规则检查的响应数据
        JSONObject responseData = resultData.getJSONObject(APP.DATA);
        List<String> matchConditionKeyList = (List<String>) responseData.get("matchConditionKeyList");
        masterChipConfigData.forEach(masterChipConfig -> {
            JSONObject masterChipConfigJson = (JSONObject) masterChipConfig;
            String key = masterChipConfigJson.getString("symbol");
            if (!matchConditionKeyList.contains(key)) {
                masterChipConfigJson.remove("value");
            }
        });
        // 返回成功响应
        return JsonUtil.getSuccess("");
    }

    /**
     * 导出项目驱动文件
     * @param data
     * @param response
     * @return
     */
    public JSONObject exportDriverFile(JSONObject data, HttpServletResponse response){
        Integer projectId = data.getInteger("projectId");
        Project project = findById(projectId);
        if (project == null){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM, "找不到对应的项目数据，请检查!");
        }
        List<ProjectMasterChipConfig> masterChipConfigList = projectMasterChipConfigService.findByProperty(ProjectMasterChipConfig::getProjectId,projectId);
        List<ProjectSlaveChipConfig> slaveChipConfigList = projectSlaveChipConfigService.findByProperty(ProjectSlaveChipConfig::getProjectId,projectId);
        if (masterChipConfigList.isEmpty() || slaveChipConfigList.isEmpty()){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND, "配置未保存或未生效!");
        }
        ProjectMasterChipConfig masterChipConfig = masterChipConfigList.get(0);
        DriverLibrary masterDriverLibrary = driverLibraryService.findOneByProperty("chipId",masterChipConfig.getChipId());
        if (masterDriverLibrary == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND, "请先添加主控驱动工程!");
        }
        Integer masterDriverLibraryId = masterDriverLibrary.getDriverLibraryId();
        List<DriverLibraryDirectory> directoryList = driverLibraryDirectoryService.findByProperty(DriverLibraryDirectory::getDriverLibraryId,masterDriverLibraryId);
        DriverLibraryDirectory directory = directoryList.stream().filter(e ->e.getParentDirectoryId().equals(0)).findFirst().orElse(null);
        //List<Map<String,Object>> directoryMapList = driverLibraryDirectoryService.getBaseMapper().oneLevelDirectory(directoryId);
        List<Map<String,Object>> directoryMapList = driverLibraryDirectoryService.oneLevelDirectory(directoryList,directory);
        List<Integer> fileDirectoryIds = directoryMapList.stream().filter(e -> Objects.equals(e.get("is_file"),true)).map(e ->(Integer)e.get("directory_id")).collect(Collectors.toList());
        //当前时间
        Date now = new Date();
        //文件修改时间标识符
        String fileModificationTimeSymbol = "GenerateNotesTime";
        List<Files> filesList = filesService.getFileList(FileRelationTypeEnum.DRIVER_PROJECT.getRelationTypeId(),fileDirectoryIds);
        String nanoTime = String.valueOf(System.nanoTime());
        //保存需下载文件夹临时路径
        String targetTempFilePath = baseFilePath + "files/" + "temp/" + nanoTime + "/";
        driverLibraryDirectoryService.copyFilesToDirectoryTree(targetTempFilePath,filesList,directoryMapList);
        List<DriverLibraryConfig> driverLibraryConfigList = driverLibraryConfigService.findByProperty(DriverLibraryConfig::getDriverLibraryId,masterDriverLibraryId);
        DriverLibraryConfig hHeaderConfig = driverLibraryConfigList.stream().filter(e -> DriverLibraryConfigTypeEnum.H_HEADER.getId().equals(e.getType())).findFirst().orElse(null);
        DriverLibraryConfig cSourceConfig = driverLibraryConfigList.stream().filter(e -> DriverLibraryConfigTypeEnum.C_SOURCE.getId().equals(e.getType())).findFirst().orElse(null);
        DriverLibraryConfig driverDocumentationConfig = driverLibraryConfigList.stream().filter(e -> DriverLibraryConfigTypeEnum.DRIVER_DOCUMENTATION.getId().equals(e.getType())).findFirst().orElse(null);
        List<DriverLibraryConfig> clockTemplateConfigList = driverLibraryConfigList.stream().filter(e -> DriverLibraryConfigTypeEnum.CLOCK_TEMPLATE.getId().equals(e.getType())).collect(Collectors.toList());
        DriverLibraryConfig otherDriverConfig = driverLibraryConfigList.stream().filter(e -> DriverLibraryConfigTypeEnum.OTHER_DRIVER.getId().equals(e.getType())).findFirst().orElse(null);
        //.h头文件目录
        String hHeaderFolder = null;
        if (hHeaderConfig != null) {
            DriverLibraryDirectory hHeaderDirectory = directoryList.stream().filter(d ->d.getDirectoryId().equals(hHeaderConfig.getDirectoryId())).findFirst().orElse(null);
            if (hHeaderDirectory != null){
                hHeaderFolder = driverLibraryDirectoryService.getParentDirectoryNames(directoryMapList, hHeaderDirectory.getDirectoryId());
            }
        }
        //.c源文件目录
        String cSourceFolder = null;
        if (cSourceConfig != null) {
            DriverLibraryDirectory cSourceDirectory = directoryList.stream().filter(d ->d.getDirectoryId().equals(cSourceConfig.getDirectoryId())).findFirst().orElse(null);
            if (cSourceDirectory != null){
                cSourceFolder = driverLibraryDirectoryService.getParentDirectoryNames(directoryMapList, cSourceDirectory.getDirectoryId());
            }
        }
        //驱动说明文档目录
        String driverDocumentationFolder= null;
        if (driverDocumentationConfig != null) {
            DriverLibraryDirectory driverDocumentationDirectory = directoryList.stream().filter(d ->d.getDirectoryId().equals(driverDocumentationConfig.getDirectoryId())).findFirst().orElse(null);
            if (driverDocumentationDirectory != null){
                driverDocumentationFolder = driverLibraryDirectoryService.getParentDirectoryNames(directoryMapList, driverDocumentationDirectory.getDirectoryId());
            }
        }
        //其他驱动文件目录
        String otherDriverFolder = null;
        if (otherDriverConfig != null) {
            DriverLibraryDirectory otherDriverDirectory = directoryList.stream().filter(d ->d.getDirectoryId().equals(otherDriverConfig.getDirectoryId())).findFirst().orElse(null);
            if (otherDriverDirectory != null){
                otherDriverFolder = driverLibraryDirectoryService.getParentDirectoryNames(directoryMapList, otherDriverDirectory.getDirectoryId());
            }
        }
        if (!StringUtils.isAllBlank(hHeaderFolder,cSourceFolder,driverDocumentationFolder,otherDriverFolder)){
            for (ProjectSlaveChipConfig slaveChipConfig : slaveChipConfigList){
                Integer slaveDriverLibraryId = slaveChipConfig.getDriverLibraryId();
                if (!StringUtils.isAllBlank(hHeaderFolder,cSourceFolder,otherDriverFolder)){
                    ChipControlMode chipControlMode = chipControlModeService.getOneByProperties(slaveDriverLibraryId,slaveChipConfig.getControlModeName());
                    List<ChipControlModeInterface> slaveInterfaceList = chipControlMode == null ? new ArrayList<>() : chipControlModeInterfaceService.findByProperty(ChipControlModeInterface::getControlModeId,chipControlMode.getControlModeId());
                    List<ProjectSlaveChipConfigInterface> projectSlaveInterfaceConfigList = projectSlaveChipConfigInterfaceService.findByProperty(ProjectSlaveChipConfigInterface::getProjectSlaveChipConfigId,slaveChipConfig.getProjectSlaveChipConfigId());
                    Map<String,String> configMap = formPropertyService.matchSingleInstanceWithProperties(FormBusinessModuleEnum.SLAVE_CHIP_PARAMETER.getModuleId(),slaveDriverLibraryId,slaveChipConfig.getProjectSlaveChipConfigId().toString());
                    configMap.put(fileModificationTimeSymbol,DateUtil.dateToString(now,DateUtil.FORMAT_LONG_SLASH));
                    configMap.put("control_mode",chipControlMode == null ? "" : chipControlMode.getValue());
                    for (ProjectSlaveChipConfigInterface projectSlaveChipConfigInterface : projectSlaveInterfaceConfigList){
                        ChipControlModeInterface chipControlModeInterface = slaveInterfaceList.stream().filter(e ->e.getControlModeInterfaceId().equals(projectSlaveChipConfigInterface.getSlaveChipControlModeInterfaceId())).findFirst().orElse(null);
                        if (chipControlModeInterface != null){
                            configMap.put(chipControlModeInterface.getSymbol(),"hardwired".equals(projectSlaveChipConfigInterface.getSlaveChipInterfaceTypeName()) ? "0" : projectSlaveChipConfigInterface.getMasterChipResourceName());
                        }
                    }
                    List<ProjectSlaveChipConfigInterfaceParameter> projectSlaveInterfaceParameterList = projectSlaveChipConfigInterfaceParameterService.findByProperty(ProjectSlaveChipConfigInterfaceParameter::getProjectSlaveChipConfigId,slaveChipConfig.getProjectSlaveChipConfigId());
                    for (ProjectSlaveChipConfigInterfaceParameter projectSlaveChipConfigInterfaceParameter : projectSlaveInterfaceParameterList){
                        if (StringUtils.isNotBlank(projectSlaveChipConfigInterfaceParameter.getValue())){
                            configMap.put(projectSlaveChipConfigInterfaceParameter.getSymbol(),projectSlaveChipConfigInterfaceParameter.getValue());
                        }
                    }
                    List<ProjectSlaveChipConfigInterfacePin> configInterfacePinList = projectSlaveChipConfigInterfacePinService.findByProperty(ProjectSlaveChipConfigInterfacePin::getProjectSlaveChipConfigId,slaveChipConfig.getProjectSlaveChipConfigId());
                    List<ProjectSlaveChipConfigInterfacePinParameter> configInterfacePinParameterList = projectSlaveChipConfigInterfacePinParameterService.findByProperty(ProjectSlaveChipConfigInterfacePinParameter::getProjectSlaveChipConfigId,slaveChipConfig.getProjectSlaveChipConfigId());
                    List<Map<String,String>> configMapList = new ArrayList<>();
                    for (ProjectSlaveChipConfigInterfacePin configInterfacePin : configInterfacePinList){
                        Map<String,String> gpioConfigMap = new HashMap<>();
                        gpioConfigMap.put("interface_resource",configInterfacePin.getMasterChipPinName());
                        List<ProjectSlaveChipConfigInterfacePinParameter> configPinParameterList = configInterfacePinParameterList.stream().filter(e ->e.getProjectSlaveChipConfigInterfacePinId().equals(configInterfacePin.getProjectSlaveChipConfigInterfacePinId())).collect(Collectors.toList());
                        for (ProjectSlaveChipConfigInterfacePinParameter configInterfacePinParameter : configPinParameterList){
                            if(StringUtils.isNotBlank(configInterfacePinParameter.getValue())){
                                gpioConfigMap.put(configInterfacePinParameter.getSymbol(),configInterfacePinParameter.getValue());
                            }
                        }
                        configMapList.add(gpioConfigMap);
                    }
                    //把被控驱动所有.h文件复制到主控工程.h文件目录中
                    if (hHeaderFolder != null){
                        List<Files> hHeaderFiles = filesService.getFileList(FileRelationTypeEnum.H_HEADER.getRelationTypeId(),slaveDriverLibraryId);
                        String hHeaderFolderPath = targetTempFilePath + hHeaderFolder + "/";
                        copyAndReplaceFileContent(hHeaderFiles,hHeaderFolderPath,configMap,configMapList);
                    }
                    //把被控驱动所有.c文件复制到主控工程.c文件目录中
                    if (cSourceFolder != null){
                        List<Files> cSourceFiles = filesService.getFileList(FileRelationTypeEnum.C_SOURCE.getRelationTypeId(),slaveDriverLibraryId);
                        String cSourceFolderPath = targetTempFilePath + cSourceFolder + "/";
                        copyAndReplaceFileContent(cSourceFiles,cSourceFolderPath,configMap,configMapList);
                    }
                    //把被控驱动所有其他驱动文件复制到主控工程其他驱动文件目录中
                    if (otherDriverFolder != null){
                        List<Files> otherDriverFiles = filesService.getFileList(FileRelationTypeEnum.OTHER_DRIVER.getRelationTypeId(),slaveDriverLibraryId);
                        String otherDriverFolderPath = targetTempFilePath + otherDriverFolder + "/";
                        copyAndReplaceFileContent(otherDriverFiles,otherDriverFolderPath,configMap,configMapList);
                    }
                }
                if (driverDocumentationFolder != null){
                    List<Files> driverDocumentationFiles = filesService.getFileList(FileRelationTypeEnum.DRIVER_DOCUMENTATION.getRelationTypeId(),slaveDriverLibraryId);
                    String driverDocumentationFolderPath = targetTempFilePath + driverDocumentationFolder + "/";
                    copyAndReplaceFileContent(driverDocumentationFiles,driverDocumentationFolderPath,null,null);
                }
            }
        }
        //填充时钟模板文件参数值
        if (!clockTemplateConfigList.isEmpty()){
            Set<Integer> clockTemplateDirectoryIds = clockTemplateConfigList.stream().map(DriverLibraryConfig::getDirectoryId).collect(Collectors.toSet());
            List<DriverLibraryDirectory> clockTemplateDirectoryList = directoryList.stream().filter(d ->clockTemplateDirectoryIds.contains(d.getDirectoryId())).collect(Collectors.toList());
            List<Files> clockTemplateFileList = filesList.stream().filter(f ->clockTemplateDirectoryIds.contains(f.getRelationId())).collect(Collectors.toList());
            if (!clockTemplateDirectoryList.isEmpty() && !clockTemplateFileList.isEmpty()){
                List<ProjectMasterChipClockParameter> projectMasterChipClockParameterList = projectMasterChipClockParameterService.findByProperty(ProjectMasterChipClockParameter::getProjectMasterChipConfigId,masterChipConfig.getProjectMasterChipConfigId());
                if (!projectMasterChipClockParameterList.isEmpty()){
                    Map<String,String> clockConfigMap = new HashMap<>();
                    clockConfigMap.put(fileModificationTimeSymbol,DateUtil.dateToString(now,DateUtil.FORMAT_LONG_SLASH));
                    for (ProjectMasterChipClockParameter projectMasterChipClockParameter : projectMasterChipClockParameterList){
                        if (StringUtils.isNotBlank(projectMasterChipClockParameter.getValue())){
                            clockConfigMap.put(projectMasterChipClockParameter.getSymbol(),projectMasterChipClockParameter.getValue());
                        }
                    }
                    for (Files clockTemplateFile : clockTemplateFileList){
                        String sourceFilePath = targetTempFilePath + driverLibraryDirectoryService.getParentDirectoryNames(directoryMapList, clockTemplateFile.getRelationId());
                        replaceFileContentByMap(sourceFilePath,clockConfigMap);
                    }
                }
            }
        }
        String directoryName = directory.getDirectoryName();
        //生成项目配置文件
        String sourceConfigFilePath = generateConfigFile(project);
        FileUtils.copyFile(sourceConfigFilePath,targetTempFilePath + directoryName + "/projectConfig.json");
        FileUtils.deleteFile(sourceConfigFilePath);

        String sourceFolderPath = targetTempFilePath + directoryName;
        String fileNamePrefix = project.getName() + '_' + directoryName + '_' + DateUtil.dateToString(now,DateUtil.FORMAT_LONG_CLEAN);//加上项目工程名
        CompressUtils.createCompress(response,sourceFolderPath,targetTempFilePath,fileNamePrefix);
        return JsonUtil.getSuccess("");
    }

    /**
     * 复制并替换文件内容
     * @param replaceFileList 需要替换的文件列表
     * @param folderPath      替换文件存放文件夹路径
     * @param configMap
     * @param configMapList
     */
    private void copyAndReplaceFileContent(List<Files> replaceFileList,String folderPath,Map<String,String> configMap,List<Map<String,String>> configMapList){
        for (Files files : replaceFileList){
            String sourceFilePath = folderPath + files.getFileName();
            FileUtils.copyFile(baseFilePath + files.getPath().replaceFirst("uploads/", ""),sourceFilePath);
            replaceFileContentByMap(sourceFilePath,configMap);
            replaceFileContentByList(sourceFilePath,configMapList);
        }
    }

    /**
     * 替换文件内容
     * @param sourceFilePath
     * @param configMap
     */
    private void replaceFileContentByMap(String sourceFilePath,Map<String,String> configMap){
        if (configMap != null && !configMap.isEmpty()){
            filesService.replaceFileContent(sourceFilePath,"GBK","$@{","}@$",configMap);
        }
    }

    /**
     * 替换文件内容
     * @param sourceFilePath
     * @param configMapList
     */
    private void replaceFileContentByList(String sourceFilePath,List<Map<String,String>> configMapList){
        if (configMapList != null && !configMapList.isEmpty()){
            filesService.replaceFileContent(sourceFilePath,"GBK","$@for{interfaces}{","$@{","}@$",configMapList);
        }
    }


    /**
     * 生成配置文件
     * @param project
     * @return
     */
    public String generateConfigFile(Project project) {
        JSONObject layoutContent = JSONObject.parseObject(project.getLayoutContent());
        Map<String,Object> createFileData = new LinkedHashMap<>();
        if (layoutContent.getJSONObject("content") != null) {
            JSONObject content = layoutContent.getJSONObject("content");
            JSONObject slaveChipNodeIdToEdgeIdData = new JSONObject();
            List<String> edgeIdList = new ArrayList<>();
            if (content.getJSONArray("edges") != null) {
                JSONArray edges = content.getJSONArray("edges");
                for (int i = 0; i < edges.size(); i++) {
                    JSONObject edgeData = edges.getJSONObject(i);
                    edgeIdList.add(edgeData.getString("id"));
                    slaveChipNodeIdToEdgeIdData.fluentPut(edgeData.getString("slaveChipNodeId"),edgeData.getString("id"));
                }
            }
            List<ProjectSlaveChipConfig> projectSlaveChipConfigList = projectSlaveChipConfigService.getList(edgeIdList);
            List<JSONObject> formPropertyList = formPropertyService.matchMultipleInstance(FormBusinessModuleEnum.SLAVE_CHIP_PARAMETER.getModuleId(), projectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getDriverLibraryId).collect(Collectors.toSet()));
            List<Map<String,Object>> components = new ArrayList<>();
            if (content.getJSONArray("nodes") != null) {
                List<Integer> chipIdList = new ArrayList<>();
                List<String> masterChipComponentIdList = new ArrayList<>();
                JSONArray nodes = content.getJSONArray("nodes");
                for (int i = 0; i < nodes.size(); i++) {
                    JSONObject node = nodes.getJSONObject(i);
                    JSONObject data = node.getJSONObject("data");
                    Integer chipId = data.getInteger("chipId");
                    Integer chipType = data.getInteger("chipType");
                    if (ChipTypeEnum.MASTER.getType().equals(chipType)) {
                        masterChipComponentIdList.add(node.getString("id"));
                    }
                    chipIdList.add(chipId);
                }
                List<Chip> chipList = chipService.findListByIds(chipIdList);
                List<ProjectMasterChipConfig> projectMasterChipConfigList = projectMasterChipConfigService.getList(masterChipComponentIdList);
                List<Integer> projectMasterChipConfigIdList = projectMasterChipConfigList.stream().map(ProjectMasterChipConfig::getProjectMasterChipConfigId).collect(Collectors.toList());
                List<ProjectMasterChipClockParameter> projectMasterChipClockParameterList = projectMasterChipClockParameterService.getList(projectMasterChipConfigIdList);
                for (int i = 0; i < nodes.size(); i++) {
                    JSONObject node = nodes.getJSONObject(i);
                    JSONObject data = node.getJSONObject("data");
                    Integer chipId = data.getInteger("chipId");
                    Chip chip = chipList.stream().filter(c -> chipId.equals(c.getChipId())).findFirst().orElse(null);
                    Integer chipType = data.getInteger("chipType");
                    String id = node.getString("id");
                    Map<String,Object> componentData = new LinkedHashMap<>();
                    JSONObject locationData = new JSONObject();
                    locationData.fluentPut("x", node.getInteger("x"))
                            .fluentPut("y", node.getInteger("y"));
                    componentData.put("model", chip == null || chip.getModel() == null ? "" : chip.getModel());
                    componentData.put("id", id);
                    componentData.put("location", locationData);
                    if (ChipTypeEnum.MASTER.getType().equals(chipType)) {
                        ProjectMasterChipConfig projectMasterChipConfig = projectMasterChipConfigList.stream().filter(p -> id.equals(p.getComponentId())).findFirst().orElse(null);
                        List<ProjectMasterChipClockParameter> projectMasterChipClockParameterListByConfigId = projectMasterChipClockParameterList.stream().filter(p -> projectMasterChipConfig.getProjectMasterChipConfigId().equals(p.getProjectMasterChipConfigId())).collect(Collectors.toList());
                        List<JSONObject> parameters = new ArrayList<>();
                        for (ProjectMasterChipClockParameter projectMasterChipClockParameter : projectMasterChipClockParameterListByConfigId) {
                            JSONObject parameterData = new JSONObject();
                            parameterData.fluentPut("symbol", projectMasterChipClockParameter.getSymbol() == null ? "" : projectMasterChipClockParameter.getSymbol())
                                    .fluentPut("dataType", projectMasterChipClockParameter.getDataType() == null ? "" : projectMasterChipClockParameter.getDataType())
                                    .fluentPut("value", projectMasterChipClockParameter.getValue() == null ? "" : projectMasterChipClockParameter.getValue());
                            parameters.add(parameterData);
                        }
                        componentData.put("parameters", parameters);
                    } else if (ChipTypeEnum.SLAVE.getType().equals(chipType)) {
                        String edgeId = slaveChipNodeIdToEdgeIdData.getString(id);
                        if (edgeId == null) {
                            continue;
                        }
                        ProjectSlaveChipConfig projectSlaveChipConfig = projectSlaveChipConfigList.stream().filter(p -> edgeId.equals(p.getComponentId())).findFirst().orElse(null);
                        if (projectSlaveChipConfig == null) {
                            continue;
                        }
                        List<JSONObject> formPropertyListByConfigId = formPropertyList.stream().filter(f -> projectSlaveChipConfig.getProjectSlaveChipConfigId().equals(f.getInteger("businessKey"))).collect(Collectors.toList());
                        Files chipDefinitionFile = filesService.getFileList(FileRelationTypeEnum.DRIVER_DEFINITION.getRelationTypeId(), projectSlaveChipConfig.getDriverLibraryId()).get(0);
                        String oldPath = baseFilePath + chipDefinitionFile.getPath().replaceFirst("uploads/", "");
                        String jsonStr = FileUtils.getStr(oldPath);
                        JSONObject chipData = JSON.parseObject(jsonStr, Feature.OrderedField);
                        JSONArray fileParameters = chipData.getJSONArray("parameters");
                        List<Map<String,Object>> parameters = new ArrayList<>();
                        for (int j = 0; j < fileParameters.size(); j++) {
                            JSONObject fileParameter = fileParameters.getJSONObject(j);
                            Map<String,Object> parameterData = new JSONObject();
                            if (fileParameter.getString("symbol") == null) {
                                continue;
                            }
                            JSONObject formProperty = formPropertyListByConfigId.stream().filter(f -> fileParameter.getString("symbol").equals(f.getString("propertyKey"))).findFirst().orElse(null);
                            parameterData.put("symbol", fileParameter.getString("symbol"));
                            parameterData.put("dataType", fileParameter.getString("data_type"));
                            parameterData.put("value", formProperty == null || formProperty.getString("propertyValue") == null ? "" : formProperty.getString("propertyValue"));
                            parameters.add(parameterData);
                        }
                        componentData.put("parameters", parameters);
                    }
                    components.add(componentData);
                }
                List<Integer> projectSlaveChipConfigIdList = projectSlaveChipConfigList.stream().map(ProjectSlaveChipConfig::getProjectSlaveChipConfigId).collect(Collectors.toList());
                List<ProjectSlaveChipConfigInterface> projectSlaveChipConfigInterfaceList = projectSlaveChipConfigInterfaceService.getList(projectSlaveChipConfigIdList);
                List<ProjectSlaveChipConfigInterfacePin> projectSlaveChipConfigInterfacePinList = projectSlaveChipConfigInterfacePinService.getList(projectSlaveChipConfigIdList);
                List<ProjectSlaveChipConfigInterfaceParameter> projectSlaveChipConfigInterfaceParameterList = projectSlaveChipConfigInterfaceParameterService.getList(projectSlaveChipConfigIdList);
                List<Map<String,Object>> connections = new ArrayList<>();
                if (content.getJSONArray("edges") != null) {
                    JSONArray edges = content.getJSONArray("edges");
                    for (int i = 0; i < edges.size(); i++) {
                        JSONObject edgeData = edges.getJSONObject(i);
                        String id = edgeData.getString("id");
                        Map<String,Object> connectionData = new LinkedHashMap<>();
                        JSONArray endpoints = new JSONArray();
                        endpoints.add(edgeData.getString("masterChipNodeId"));
                        endpoints.add(edgeData.getString("slaveChipNodeId"));
                        ProjectSlaveChipConfig projectSlaveChipConfig = projectSlaveChipConfigList.stream().filter(p -> id.equals(p.getComponentId())).findFirst().orElse(null);
                        List<Map<String,Object>> interfaces = new ArrayList<>();

                        if(projectSlaveChipConfig != null){
                            List<ProjectSlaveChipConfigInterface> projectSlaveChipConfigInterfaceListByConfigId = projectSlaveChipConfigInterfaceList.stream().filter(p -> projectSlaveChipConfig.getProjectSlaveChipConfigId().equals(p.getProjectSlaveChipConfigId())).collect(Collectors.toList());
                            for(ProjectSlaveChipConfigInterface projectSlaveChipConfigInterface : projectSlaveChipConfigInterfaceListByConfigId){
                                Map<String,Object> interfaceData = new LinkedHashMap<>();
                                interfaceData.put("interface",projectSlaveChipConfigInterface.getSlaveChipInterfaceName() == null ? "" : projectSlaveChipConfigInterface.getSlaveChipInterfaceName());
                                interfaceData.put("interface_type",projectSlaveChipConfigInterface.getSlaveChipInterfaceType() == null ? "" : projectSlaveChipConfigInterface.getSlaveChipInterfaceType());
                                interfaceData.put("interface_resource",projectSlaveChipConfigInterface.getMasterChipResourceName() == null ? "" : projectSlaveChipConfigInterface.getMasterChipResourceName());
                                List<ProjectSlaveChipConfigInterfacePin> projectSlaveChipConfigInterfacePinListByInterfaceId = projectSlaveChipConfigInterfacePinList.stream().filter(p -> projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId().equals(p.getProjectSlaveChipConfigInterfaceId())).collect(Collectors.toList());
                                List<Map<String,Object>> pins = new ArrayList<>();
                                for(ProjectSlaveChipConfigInterfacePin projectSlaveChipConfigInterfacePin : projectSlaveChipConfigInterfacePinListByInterfaceId){
                                    Map<String,Object> pinData = new LinkedHashMap<>();
                                    pinData.put("pin_name",projectSlaveChipConfigInterfacePin.getMasterChipPinName() == null ? "" : projectSlaveChipConfigInterfacePin.getMasterChipPinName());
                                    pinData.put("pin_code",projectSlaveChipConfigInterfacePin.getMasterChipPinCode() == null ? "" : projectSlaveChipConfigInterfacePin.getMasterChipPinCode());
                                    pins.add(pinData);
                                }
                                List<ProjectSlaveChipConfigInterfaceParameter> projectSlaveChipConfigInterfaceParameterListByInterfaceId = projectSlaveChipConfigInterfaceParameterList.stream().filter(p -> projectSlaveChipConfigInterface.getProjectSlaveChipConfigInterfaceId().equals(p.getProjectSlaveChipConfigInterfaceId())).collect(Collectors.toList());
                                List<Map<String,Object>> interfaceParameters = new ArrayList<>();
                                for(ProjectSlaveChipConfigInterfaceParameter projectSlaveChipConfigInterfaceParameter : projectSlaveChipConfigInterfaceParameterListByInterfaceId){
                                    Map<String,Object> interfaceParameterData = new LinkedHashMap<>();
                                    interfaceParameterData.put("symbol",projectSlaveChipConfigInterfaceParameter.getSymbol() == null ? "" : projectSlaveChipConfigInterfaceParameter.getSymbol());
                                    interfaceParameterData.put("data_type",projectSlaveChipConfigInterfaceParameter.getDataType() == null ? "" : projectSlaveChipConfigInterfaceParameter.getDataType());
                                    interfaceParameterData.put("value",projectSlaveChipConfigInterfaceParameter.getValue() == null ? "" : projectSlaveChipConfigInterfaceParameter.getValue());
                                    interfaceParameters.add(interfaceParameterData);
                                }
                                interfaceData.put("pins",pins);
                                interfaceData.put("interface_parameters",interfaceParameters);
                                interfaces.add(interfaceData);

                            }
                        }
                        connectionData.put("endpoints",endpoints);
                        connectionData.put("control_mode",projectSlaveChipConfig.getControlModeName() == null ? "" : projectSlaveChipConfig.getControlModeName());
                        connectionData.put("interfaces",interfaces);
                        connections.add(connectionData);
                    }
                }
                createFileData.put("components", components);
                createFileData.put("connections",connections);
            }
        }
        String filePath = filesService.createJsonFile(createFileData);
        return filePath;
    }

    /**
     * 依赖规则检查
     * @param webData
     * @return
     */
    public JSONObject dependencyRuleCheck(JSONObject webData){
        Integer chipId = webData.getInteger("chipId");
        Integer ruleSetType = webData.getInteger("ruleSetType");
        Map<SFunction<RuleSet, ?>, Object> ruleSetFieldValueMap = new HashMap<>();
        ruleSetFieldValueMap.put(RuleSet::getType,ruleSetType);
        if(RuleSetTypeEnum.DRIVER_CONFIGURATION.getId().equals(ruleSetType)){
            Integer driverLibraryId = webData.getInteger("driverLibraryId");
            ruleSetFieldValueMap.put(RuleSet::getDriverLibraryId,driverLibraryId);
        }else{
            ruleSetFieldValueMap.put(RuleSet::getChipId,chipId);
        }
        List<RuleSet> ruleSetList = ruleSetService.findByProperties(ruleSetFieldValueMap);
        if(ruleSetList.isEmpty()){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的规则集校验");
        }
        if(ruleSetList.size() > 1){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"存在多个规则集，请检查");
        }
        RuleSet ruleSet = ruleSetList.get(0);
        JSONObject parameterData = webData.getJSONObject("parameterData");
        Map<SFunction<Rule, ?>, Object> ruleFieldValueMap = new HashMap<>();
        ruleFieldValueMap.put(Rule::getRuleSetId,ruleSet.getRuleSetId());
        if(webData.getInteger("objectId") != null){
            ruleFieldValueMap.put(Rule::getObjectId,webData.getInteger("objectId"));
        }
        List<Rule> ruleList = ruleService.findByProperties(ruleFieldValueMap);
        List<Integer> ruleIdList = ruleList.stream().map(Rule::getRuleId).collect(Collectors.toList());
        List<Condition> conditionList = conditionService.getListByRuleIdList(ruleIdList);
        List<Integer> matchRuleIdList = new ArrayList<>();
        List<String> matchRuleSatisfyList = new ArrayList<>();
        handleDependencyCondition(parameterData, ruleList, conditionList, matchRuleIdList, matchRuleSatisfyList);
        JSONObject data = new JSONObject();
        // 前端需联动改，暂不修改key
        data.fluentPut("matchConditionKeyList",matchRuleSatisfyList)
                .fluentPut("matchConditionIdList",matchRuleIdList);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,data);
    }

    /**
     * 处理依赖条件
     * @param parameterData
     * @param ruleList
     * @param conditionList
     * @param matchRuleIdList
     * @param matchRuleSatisfyList
     */
    public void handleDependencyCondition(JSONObject parameterData, List<Rule> ruleList, List<Condition> conditionList, List<Integer> matchRuleIdList, List<String> matchRuleSatisfyList) {
        for(Rule rule : ruleList){
            List<Condition> conditionListRuleId = conditionList.stream().filter(c -> rule.getRuleId().equals(c.getRuleId())).collect(Collectors.toList());
            if(RuleTypeEnum.DEPENDENCY_RULE.equals(rule.getType())){
                Boolean isAllPass = true;
                for(Condition condition : conditionListRuleId){
                    String standardSpecification = condition.getStandardSpecification();
                    String expression = parseExpression(standardSpecification,parameterData);
                    boolean evaluateExpression = evaluateExpression(expression);
                    if(!evaluateExpression){
                        isAllPass = false;
                    }
                }
                if(isAllPass){
                    if(!matchRuleSatisfyList.contains(rule.getSatisfy())){
                        matchRuleSatisfyList.add(rule.getSatisfy());
                        matchRuleIdList.add(rule.getRuleId());
                    }
                }
            }else{
                if(rule.getPrepositionRuleId() != null){
                    continue;
                }
                for(Condition condition : conditionListRuleId){
                    if(!matchRuleSatisfyList.contains(condition.getFactMode())){
                        matchRuleSatisfyList.add(condition.getFactMode());
                        matchRuleIdList.add(rule.getRuleId());
                    }
                }
            }

        }



    }

    /**
     * 多个依赖规则检查
     * @param webData
     * @return
     */
    public JSONObject multipleDependencyRuleCheck(JSONObject webData){
        JSONArray checkDataList = webData.getJSONArray("checkDataList");
        List<JSONObject> dataList = new ArrayList<>();
        //此数组最大为2，暂不考虑循环查询数据库优化
        for (int i = 0; i < checkDataList.size(); i++) {
            JSONObject data = new JSONObject();
            JSONObject checkData = checkDataList.getJSONObject(i);
            Integer chipId = checkData.getInteger("chipId");
            Integer ruleSetType = checkData.getInteger("ruleSetType");
            Map<SFunction<RuleSet, ?>, Object> ruleSetFieldValueMap = new HashMap<>();
            ruleSetFieldValueMap.put(RuleSet::getType,ruleSetType);
            if(RuleSetTypeEnum.DRIVER_CONFIGURATION.getId().equals(ruleSetType)){
                Integer driverLibraryId = webData.getInteger("driverLibraryId");
                ruleSetFieldValueMap.put(RuleSet::getDriverLibraryId,driverLibraryId);
            }else{
                ruleSetFieldValueMap.put(RuleSet::getChipId,chipId);
            }
            List<RuleSet> ruleSetList = ruleSetService.findByProperties(ruleSetFieldValueMap);
            if(ruleSetList.isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,String.format("checkDataList第%d项找不到对应的规则集",(i+1)));
            }
            if(ruleSetList.size() > 1){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,String.format("checkDataList第%d项存在多个规则集，请检查",(i+1)));
            }
            RuleSet ruleSet = ruleSetList.get(0);
            Map<SFunction<Rule, ?>, Object> ruleFieldValueMap = new HashMap<>();
            ruleFieldValueMap.put(Rule::getRuleSetId, ruleSet.getRuleSetId());
            List<Rule> ruleList = ruleService.findByProperties(ruleFieldValueMap);
            List<Integer> ruleIdList = ruleList.stream().map(Rule::getRuleId).collect(Collectors.toList());
            List<Condition> conditionList = conditionService.getListByRuleIdList(ruleIdList);
            JSONArray configDataList = checkData.getJSONArray("configDataList");
            List<JSONObject> returnConfigDataList = new ArrayList<>();
            for (int j = 0; j < configDataList.size(); j++) {
                JSONObject returnConfigData = new JSONObject();
                JSONObject configData = configDataList.getJSONObject(j);
                JSONObject parameterData = configData.getJSONObject("parameterData");
                List<Rule> ruleListByConfig = ruleList;
                if(configData.getInteger("objectId") != null){
                    ruleListByConfig = ruleList.stream().filter(r -> configData.getInteger("objectId").equals(r.getObjectId())).collect(Collectors.toList());
                }
                List<Integer> ruleIdListByConfig = ruleListByConfig.stream().map(Rule::getRuleId).collect(Collectors.toList());
                List<Condition> conditionListByConfig = conditionList.stream().filter(c -> ruleIdListByConfig.contains(c.getRuleId())).collect(Collectors.toList());
                List<String> matchRuleSatisfyList = new ArrayList<>();
                List<Integer> matchRuleIdList = new ArrayList<>();
                handleDependencyCondition(parameterData, ruleListByConfig, conditionListByConfig, matchRuleIdList, matchRuleSatisfyList);
                // 前端需联动改，暂不修改key
                returnConfigData.fluentPut("matchConditionKeyList",matchRuleSatisfyList);
                returnConfigData.fluentPut("matchConditionIdList",matchRuleIdList);
                returnConfigDataList.add(returnConfigData);
            }
            data.put("configDataList",returnConfigDataList);
            dataList.add(data);
        }
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,dataList);
    }

    /**
     * 解析表达式,例:sys_clk_source==HSE||(pll_source==HSE&&sys_clk_source==PLLCLK)
     * 1.将表达式拆解成sys_clk_source==HSE、pll_source==HSE、sys_clk_source==PLLCLK数组
     * 2.计算单个表达式的结果(注:获取对应字段的数据填充对应表达式，若获取不到对应字段数据，默认此表达式的结果为false)
     * 3.将计算出来的单个表达式结果替代原表达式中单个表达式，变成false||(false&&false)返回
     * @param expression
     * @param parameterData
     * @return
     */
    private String parseExpression(String expression,JSONObject parameterData) {
        String[] expressionSplit = expression.split("\\|\\||&&");
        for(String singleExpression : expressionSplit){
            singleExpression = singleExpression.replace("(","");
            singleExpression = singleExpression.replace(")","");
            singleExpression = singleExpression.trim();
            Boolean evaluateExpression = evaluateSingleExpression(singleExpression,parameterData);
            expression = expression.replace(singleExpression,Boolean.toString(evaluateExpression));
        }
        return expression;
    }

    /**
     * 计算表达式,例expression = false||(false&&false) 返回false
     * @param expression
     * @return
     */
    private boolean evaluateExpression(String expression) {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(expression);
        return exp.getValue(Boolean.class);
    }


    /**
     * 计算单个表达式
     * 例：sys_clk_source==HSE，从parameterData获取sys_clk_source字段的值(ON)，将此表达式转换成ON==HSE，计算此表达式返回true或false
     * @param operand
     * @param parameterData
     * @return
     */
    private Boolean evaluateSingleExpression(String operand, JSONObject parameterData) {
        List<String> relationalOperatorList = RelationalOperatorEnum.getOperatorList();
        String relationalOperatorJoin = StringUtils.join(relationalOperatorList, "|");
        Pattern relationalOperatorPattern = Pattern.compile(relationalOperatorJoin);
        Matcher relationalOperatorMatcher = relationalOperatorPattern.matcher(operand);
        if (relationalOperatorMatcher.find()) {
            String operator = relationalOperatorMatcher.group();
            String[] values = operand.split(Pattern.quote(operator), 2);
            if (values.length == 2) {
                String leftValue = values[0].trim();
                String rightValue = values[1].trim();
                if(parameterData.getString(leftValue) == null){
                    return false;
                }else{
                    return evaluateRelationalOperation(parameterData.getString(leftValue), operator, rightValue);
                }
            }
        }
        return false;
    }

    /**
     * 计算关系运算符
     * @param leftValue
     * @param operator
     * @param rightValue
     * @return
     */
    private boolean evaluateRelationalOperation(String leftValue, String operator, String rightValue) {
        RelationalOperatorEnum relationalOperatorEnum = RelationalOperatorEnum.getEnumByOperator(operator);
        if(relationalOperatorEnum == null){
            return false;
        }
        List<String> needJudgeIsNumberRelationalOperatorList = new ArrayList<>();
        needJudgeIsNumberRelationalOperatorList.add(RelationalOperatorEnum.GREATER_THAN.getOperator());
        needJudgeIsNumberRelationalOperatorList.add(RelationalOperatorEnum.GREATER_THAN_OR_EQUAL.getOperator());
        needJudgeIsNumberRelationalOperatorList.add(RelationalOperatorEnum.LESS_THAN.getOperator());
        needJudgeIsNumberRelationalOperatorList.add(RelationalOperatorEnum.LESS_THAN_OR_EQUAL.getOperator());
        if(!needJudgeIsNumberRelationalOperatorList.contains(operator)) {
            switch (relationalOperatorEnum) {
                case EQUAL:
                    return leftValue.equals(rightValue);
                case NOT_EQUAL:
                    return !leftValue.equals(rightValue);
                default:
                    return false;
            }
        }else{
            if (!DataUtil.isNumber(leftValue) || !DataUtil.isNumber((rightValue))) {
                return false;
            }
            BigDecimal leftNumber = new BigDecimal(leftValue);
            BigDecimal rightNumber = new BigDecimal(rightValue);
            switch (relationalOperatorEnum) {
                case GREATER_THAN:
                    return leftNumber.compareTo(rightNumber) > 0;
                case GREATER_THAN_OR_EQUAL:
                    return leftNumber.compareTo(rightNumber) >= 0;
                case LESS_THAN:
                    return leftNumber.compareTo(rightNumber) < 0;
                case LESS_THAN_OR_EQUAL:
                    return leftNumber.compareTo(rightNumber) <= 0;
                default:
                    return false;
            }
        }
    }

    /**
     * 规则检查
     * @param webData
     * @return
     */
    public JSONObject ruleCheck(JSONObject webData){
        JSONArray checkDataList = webData.getJSONArray("checkDataList");
        List<JSONObject> dataList = new ArrayList<>();
        //此数组最大为2，暂不考虑循环查询数据库优化
        for (int i = 0; i < checkDataList.size(); i++) {
            JSONObject data = new JSONObject();
            JSONObject checkData = checkDataList.getJSONObject(i);
            Integer chipId = checkData.getInteger("chipId");
            Integer ruleSetType = checkData.getInteger("ruleSetType");
            Map<SFunction<RuleSet, ?>, Object> ruleSetFieldValueMap = new HashMap<>();
            ruleSetFieldValueMap.put(RuleSet::getType,ruleSetType);
            if(RuleSetTypeEnum.DRIVER_CONFIGURATION.getId().equals(ruleSetType)){
                Integer driverLibraryId = checkData.getInteger("driverLibraryId");
                ruleSetFieldValueMap.put(RuleSet::getDriverLibraryId,driverLibraryId);
            }else{
                ruleSetFieldValueMap.put(RuleSet::getChipId,chipId);
            }
            List<RuleSet> ruleSetList = ruleSetService.findByProperties(ruleSetFieldValueMap);

            if(ruleSetList.isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,String.format("checkDataList第%d项找不到对应的规则集",(i+1)));
            }
            if(ruleSetList.size() > 1){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,String.format("checkDataList第%d项存在多个规则集，请检查",(i+1)));
            }
            RuleSet ruleSet = ruleSetList.get(0);
            Map<SFunction<Rule, ?>, Object> ruleFieldValueMap = new HashMap<>();
            ruleFieldValueMap.put(Rule::getRuleSetId, ruleSet.getRuleSetId());
            ruleFieldValueMap.put(Rule::getType, RuleTypeEnum.CONFIGURATION_RULE.getTypeId());
            List<Rule> ruleList = ruleService.findByProperties(ruleFieldValueMap);
            List<Integer> ruleIdList = ruleList.stream().map(Rule::getRuleId).collect(Collectors.toList());
            List<Condition> conditionList = conditionService.getListByRuleIdList(ruleIdList);
            JSONArray configDataList = checkData.getJSONArray("configDataList");
            List<JSONObject> returnConfigDataList = new ArrayList<>();
            for (int j = 0; j < configDataList.size(); j++) {
                JSONObject configData = configDataList.getJSONObject(j);
                JSONObject returnConfigData = new JSONObject();
                List<Rule> ruleListByConfig = ruleList;
                if(configData.getInteger("objectId") != null){
                    ruleListByConfig = ruleList.stream().filter(r -> configData.getInteger("objectId").equals(r.getObjectId())).collect(Collectors.toList());
                }
                List<Integer> ruleIdListByConfig = ruleListByConfig.stream().map(Rule::getRuleId).collect(Collectors.toList());
                List<Condition> conditionListByConfig = conditionList.stream().filter(c -> ruleIdListByConfig.contains(c.getRuleId())).collect(Collectors.toList());
                JSONObject parameterData = configData.getJSONObject("parameterData");
                List<String> notMatchConditionKeyList = new ArrayList<>();
                List<Integer> notMatchConditionIdList = new ArrayList<>();
                for(Map.Entry<String, Object> entry : parameterData.entrySet()){
                    String key = entry.getKey();
                    String value = entry.getValue().toString();
                    List<Condition> conditionListByKey = conditionListByConfig.stream().filter(c -> key.equals(c.getFactMode())).collect(Collectors.toList());
                    for(Condition condition : conditionListByKey){
                        if(notMatchConditionKeyList.contains(key)){
                            continue;
                        }
                        if(ComparatorEnum.IN_SET.getId().equals(condition.getComparator())){
                            String[] standardSpecificationSplit = condition.getStandardSpecification().split(",");
                            if(!DataUtil.isContainsString(standardSpecificationSplit,value)){
                                notMatchConditionKeyList.add(key);
                                notMatchConditionIdList.add(condition.getConditionId());
                                continue;
                            }
                        }else if(ComparatorEnum.LESS_THAN_EQUAL.getId().equals(condition.getComparator()) || ComparatorEnum.GREATER_THAN_EQUAL.getId().equals(condition.getComparator())){
                            if(!DataUtil.isNumber(value) || !DataUtil.isNumber(condition.getStandardSpecification())){
                                notMatchConditionKeyList.add(key);
                                notMatchConditionIdList.add(condition.getConditionId());
                                continue;
                            }
                            BigDecimal valueNumber = new BigDecimal(value);
                            BigDecimal standardSpecificationNumber = new BigDecimal(condition.getStandardSpecification());
                            if(ComparatorEnum.LESS_THAN_EQUAL.getId().equals(condition.getComparator())){
                                //事实方式值大于标准规范,
                                if (valueNumber.compareTo(standardSpecificationNumber) == 1){
                                    notMatchConditionKeyList.add(key);
                                    notMatchConditionIdList.add(condition.getConditionId());
                                    continue;
                                }
                            }
                            if(ComparatorEnum.GREATER_THAN_EQUAL.getId().equals(condition.getComparator())){
                                if (valueNumber.compareTo(standardSpecificationNumber) == -1){
                                    notMatchConditionKeyList.add(key);
                                    notMatchConditionIdList.add(condition.getConditionId());
                                    continue;
                                }
                            }
                        }
                    }
                }
                returnConfigData.fluentPut("notMatchConditionKeyList",notMatchConditionKeyList)
                        .fluentPut("notMatchConditionIdList",notMatchConditionIdList);
                returnConfigDataList.add(returnConfigData);
            }
            data.fluentPut("configDataList",returnConfigDataList);
            dataList.add(data);
        }
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,dataList);
    }

}
